Merge pull request #2003 from esdrubal/seq_test_fix2
authorMarcos Henrich <marcoshenrich@gmail.com>
Fri, 28 Aug 2015 12:21:00 +0000 (13:21 +0100)
committerMarcos Henrich <marcoshenrich@gmail.com>
Fri, 28 Aug 2015 12:21:00 +0000 (13:21 +0100)
[runtime] Fix test_op_il_seq_point in amd64.

283 files changed:
configure.ac
eglib/configure.ac
eglib/src/Makefile.am
eglib/src/gspawn.c
eglib/src/gunicode.c
external/ikvm
external/referencesource
ikvm-native/Makefile.am
mcs/build/profiles/xammac_net_4_5.make
mcs/class/Facades/Makefile
mcs/class/Facades/System.ServiceModel.Duplex/TypeForwarders.cs
mcs/class/Facades/System.ServiceModel.NetTcp/TypeForwarders.cs
mcs/class/Makefile
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Expression.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ExpressionCollection.cs
mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/MessageTest.cs
mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TaskItem.cs
mcs/class/Mono.Data.Sqlite/Test/Bug27864.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/Mono.Posix/Mono.Posix-tests-net_4_5.csproj
mcs/class/Mono.Posix/Mono.Posix_test.dll.sources
mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs
mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs
mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs
mcs/class/Mono.Posix/Test/Mono.Unix.Android/TestHelper.cs [new file with mode: 0644]
mcs/class/Mono.Posix/Test/Mono.Unix.Native/RealTimeSignumTests.cs
mcs/class/Mono.Posix/Test/Mono.Unix.Native/SocketTest.cs [new file with mode: 0644]
mcs/class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs
mcs/class/System.Core/xammac_net_4_5_System.Core.dll.sources
mcs/class/System.Data/xammac_net_4_5_System.Data.dll.sources
mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs
mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs
mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs
mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources [deleted file]
mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources [deleted file]
mcs/class/System.Runtime.Remoting/Test/HttpServerChannelTests.cs
mcs/class/System.Runtime.Serialization/xammac_net_4_5_System.Runtime.Serialization.dll.sources
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs
mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs
mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources
mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug32886Test.cs [new file with mode: 0644]
mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug652331Test.cs
mcs/class/System/System.Diagnostics/Process.cs
mcs/class/System/System.IO/KeventWatcher.cs
mcs/class/System/System.IO/MonoSyncFileStream.cs [deleted file]
mcs/class/System/System.Net/ChunkStream.cs
mcs/class/System/System.Net/ServicePoint.cs
mcs/class/System/System.Net/WebConnectionStream.cs
mcs/class/System/System.dll.sources
mcs/class/System/System/UriBuilder.cs
mcs/class/System/Test/System.Diagnostics/ProcessTest.cs
mcs/class/System/Test/System.Net.Security/SslStreamTest.cs
mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs
mcs/class/System/Test/System/UriBuilderTest.cs
mcs/class/System/mobile_System.dll.sources
mcs/class/WindowsBase/System.IO.Packaging/PackagePart.cs
mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs
mcs/class/corlib/ReferenceSources/TextInfo.cs
mcs/class/corlib/System.Diagnostics/StackTrace.cs
mcs/class/corlib/System.IO/FileStream.cs
mcs/class/corlib/System.IO/IntPtrStream.cs [deleted file]
mcs/class/corlib/System.IO/MonoIO.cs
mcs/class/corlib/System.Reflection/MonoEvent.cs
mcs/class/corlib/System.Reflection/MonoProperty.cs
mcs/class/corlib/System.Threading/Monitor.cs
mcs/class/corlib/System.Threading/ThreadPool.cs [deleted file]
mcs/class/corlib/System/Console.cs
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/System/Exception.cs
mcs/class/corlib/System/Math.cs [deleted file]
mcs/class/corlib/System/TimeZoneInfo.Android.cs
mcs/class/corlib/System/TimeZoneInfo.MonoTouch.cs
mcs/class/corlib/System/TimeZoneInfo.cs
mcs/class/corlib/Test/System.IO.IsolatedStorage/IsolatedStorageFileTest.cs
mcs/class/corlib/Test/System.IO/FileStreamTest.cs
mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs
mcs/class/corlib/Test/System.Reflection/AssemblyNameTest.cs
mcs/class/corlib/Test/System.Reflection/ConstructorInfoTest.cs
mcs/class/corlib/Test/System.Reflection/EventInfoTest.cs
mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs
mcs/class/corlib/Test/System.Reflection/PropertyInfoTest.cs
mcs/class/corlib/Test/System.Runtime.ExceptionServices/ExceptionDispatchInfoTest.cs
mcs/class/corlib/Test/System.Threading/ThreadTest.cs
mcs/class/corlib/Test/System/MathTest.cs
mcs/class/corlib/Test/System/TimeZoneInfoTest.cs
mcs/class/corlib/corlib.dll.sources
mcs/ilasm/parser/ILParser.jay
mcs/ilasm/scanner/ILTables.cs
mcs/mcs/assembly.cs
mcs/mcs/context.cs
mcs/mcs/cs-tokenizer.cs
mcs/mcs/ecore.cs
mcs/mcs/flowanalysis.cs
mcs/mcs/lambda.cs
mcs/mcs/statement.cs
mcs/tests/gtest-633.cs [new file with mode: 0644]
mcs/tests/test-async-68.cs [new file with mode: 0644]
mcs/tests/test-interpolation-08.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml
mcs/tools/mkbundle/mkbundle.cs
mcs/tools/mono-symbolicate/Makefile
mcs/tools/monop/Makefile
mono/arch/arm/tramp.c [deleted file]
mono/io-layer/handles-private.h
mono/io-layer/handles.c
mono/io-layer/io.c
mono/io-layer/io.h
mono/io-layer/processes.c
mono/io-layer/thread-private.h
mono/io-layer/threads.h
mono/io-layer/wait.c
mono/io-layer/wapi-remap.h
mono/io-layer/wthreads.c
mono/metadata/Makefile.am
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/domain-internals.h
mono/metadata/domain.c [changed mode: 0755->0644]
mono/metadata/file-io.c
mono/metadata/file-io.h
mono/metadata/filewatcher.c
mono/metadata/filewatcher.h
mono/metadata/gc-stats.c
mono/metadata/gc.c
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/lock-tracer.c
mono/metadata/marshal.c
mono/metadata/metadata.c
mono/metadata/monitor.c
mono/metadata/monitor.h
mono/metadata/mono-hash.c
mono/metadata/mono-hash.h
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/process.c
mono/metadata/reflection.c
mono/metadata/sgen-os-coop.c [new file with mode: 0644]
mono/metadata/sgen-os-mach.c
mono/metadata/sgen-os-posix.c
mono/metadata/sgen-os-win32.c
mono/metadata/socket-io.c
mono/metadata/sysmath.c
mono/metadata/sysmath.h
mono/metadata/threadpool-ms-io-epoll.c
mono/metadata/threadpool-ms-io-kqueue.c
mono/metadata/threadpool-ms-io-poll.c
mono/metadata/threadpool-ms-io.c
mono/metadata/threadpool-ms.c
mono/metadata/threads.c
mono/mini/Makefile.am.in
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/aot-tests.cs
mono/mini/branch-opts.c
mono/mini/cpu-arm.md
mono/mini/cpu-arm64.md
mono/mini/cpu-ppc.md
mono/mini/cpu-x86.md
mono/mini/debugger-agent.c
mono/mini/dwarfwriter.c
mono/mini/exceptions-amd64.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-ia64.c
mono/mini/exceptions-mips.c
mono/mini/exceptions-ppc.c
mono/mini/exceptions-s390x.c
mono/mini/exceptions-sparc.c
mono/mini/exceptions-x86.c
mono/mini/gshared.cs
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h
mono/mini/mini-arm-tls.S
mono/mini/mini-arm-tls.h
mono/mini/mini-arm.c
mono/mini/mini-darwin.c
mono/mini/mini-exceptions.c
mono/mini/mini-gc.c
mono/mini/mini-ia64.c
mono/mini/mini-llvm-cpp.cpp
mono/mini/mini-llvm.c
mono/mini/mini-mips.c
mono/mini/mini-ops.h
mono/mini/mini-posix.c
mono/mini/mini-ppc.c
mono/mini/mini-ppc.h
mono/mini/mini-runtime.c
mono/mini/mini-s390x.c
mono/mini/mini-s390x.h
mono/mini/mini-sparc.c
mono/mini/mini-trampolines.c
mono/mini/mini-unwind.h
mono/mini/mini-x86.c
mono/mini/mini-x86.h
mono/mini/mini.c
mono/mini/mini.h
mono/mini/seq-points.c
mono/mini/tasklets.c
mono/mini/tramp-amd64.c
mono/mini/tramp-arm.c
mono/mini/tramp-ia64.c
mono/mini/tramp-mips.c
mono/mini/tramp-ppc.c
mono/mini/tramp-s390x.c
mono/mini/tramp-sparc.c
mono/mini/tramp-x86.c
mono/mini/unwind.c
mono/profiler/decode.c
mono/profiler/mono-codeanalyst.c [deleted file]
mono/profiler/proflog.c
mono/profiler/proflog.h
mono/sgen/sgen-archdep.h
mono/sgen/sgen-gc.c
mono/sgen/sgen-gc.h
mono/sgen/sgen-los.c
mono/tests/Makefile.am
mono/tests/dynamic-method-stack-traces.cs [new file with mode: 0644]
mono/tests/libtest.c
mono/tests/monitor-resurrection.cs
mono/tests/shared-generic-synchronized.2.cs
mono/tests/suspend-stress-test.cs [new file with mode: 0644]
mono/tests/synchronized.cs
mono/tests/unhandled-exception.cs [new file with mode: 0644]
mono/unit-tests/test-conc-hashtable.c
mono/utils/Makefile.am
mono/utils/checked-build.c [new file with mode: 0644]
mono/utils/checked-build.h [new file with mode: 0644]
mono/utils/mono-compiler.h
mono/utils/mono-conc-hashtable.c
mono/utils/mono-conc-hashtable.h
mono/utils/mono-context.h
mono/utils/mono-logger-internal.h
mono/utils/mono-logger.c
mono/utils/mono-stack-unwinding.h
mono/utils/mono-threads-api.h [new file with mode: 0644]
mono/utils/mono-threads-coop.c
mono/utils/mono-threads-coop.h
mono/utils/mono-threads-mach.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-state-machine.c
mono/utils/mono-threads-windows.c [changed mode: 0755->0644]
mono/utils/mono-threads.c
mono/utils/mono-threads.h
mono/utils/valgrind.h
msvc/eglib.vcxproj
msvc/genmdesc.vcxproj
msvc/libgc.vcxproj
msvc/libmono.vcxproj
msvc/libmonoruntime.vcxproj
msvc/libmonoutils.vcxproj
msvc/libtest.vcxproj
msvc/mono.def
msvc/mono.vcxproj
msvc/monodiet.vcxproj
msvc/monodis.vcxproj
msvc/monograph.vcxproj
msvc/monoposixhelper.vcxproj
msvc/monosgen.def
msvc/monosgen64.def [deleted file]
msvc/pedump.vcxproj
msvc/test-invoke.vcxproj
msvc/test-metadata.vcxproj
msvc/test_eglib.vcxproj
msvc/teste.vcxproj
runtime/Makefile.am
scripts/mono-find-provides.in
support/Makefile.am
support/errno.c
support/map.c
support/map.h
support/mph.h
support/sys-socket.c [new file with mode: 0644]
winconfig.h

index 00d0aa5ff142e10a4068c16a106e0a9516796ae2..e26a851de63b8bdd8fd3f4c0a498b33ed824c84a 100644 (file)
@@ -77,17 +77,10 @@ has_dtrace=no
 parallel_mark=yes
 ikvm_native=yes
 
-case "$host" in
-       powerpc*-*-linux*)
-               # https://bugzilla.novell.com/show_bug.cgi?id=504411
-               disable_munmap=yes
-       ;;
-esac
-
 host_win32=no
 target_win32=no
 platform_android=no
-platform_darwin=no
+host_darwin=no
 case "$host" in
        *-mingw*|*-*-cygwin*)
                AC_DEFINE(DISABLE_PORTABILITY,1,[Disable the io-portability layer])
@@ -118,7 +111,6 @@ case "$host" in
                libgc_configure_args="$libgc_configure_args --enable-win32-dllmain=yes"
                ;;
        *-*-*netbsd*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -D_REENTRANT -DGC_NETBSD_THREADS -D_GNU_SOURCE"
                libmono_cflags="-D_REENTRANT"
                LDFLAGS="$LDFLAGS -pthread"
@@ -131,7 +123,6 @@ case "$host" in
                use_sigposix=yes
                ;;
        *-*-kfreebsd*-gnu)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP -DTHREAD_LOCAL_ALLOC -pthread"
                libmono_cflags="-D_REENTRANT -DTHREAD_LOCAL_ALLOC -pthread"
                libmono_ldflags="-lpthread -pthread"
@@ -142,7 +133,6 @@ case "$host" in
                use_sigposix=yes
                ;;
        *-*-*freebsd*)
-               host_win32=no
                if test "x$PTHREAD_CFLAGS" = "x"; then
                        CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS"
                        libmono_cflags=
@@ -166,7 +156,6 @@ case "$host" in
                has_dtrace=yes
                ;;
        *-*-*openbsd*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_OPENBSD_THREADS -DPLATFORM_BSD -D_REENTRANT -DUSE_MMAP"
                if test "x$disable_munmap" != "xyes"; then
                CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
@@ -181,7 +170,6 @@ case "$host" in
                use_sigposix=yes
                ;;
        *-*-linux-android*)
-               host_win32=no
                platform_android=yes
                AC_DEFINE(PLATFORM_ANDROID,1,[Targeting the Android platform])
                AC_DEFINE(TARGET_ANDROID,1,[Targeting the Android platform])
@@ -220,7 +208,6 @@ case "$host" in
                mono_cv_clang=no
                ;;
        *-*-linux*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP"
                if test "x$disable_munmap" != "xyes"; then
                        CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
@@ -239,10 +226,13 @@ case "$host" in
                        support_boehm=no
                        with_gc=sgen
                        ;;
+               powerpc*-*-linux*)
+                       # https://bugzilla.novell.com/show_bug.cgi?id=504411
+                       disable_munmap=yes
+                       ;;
                esac
                ;;
        *-*-nacl*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP"
                if test "x$disable_munmap" != "xyes"; then
                        CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
@@ -256,7 +246,6 @@ case "$host" in
                AC_DEFINE(DISABLE_ATTACH, 1, [Disable agent attach support])
                ;;
        *-*-hpux*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -DGC_HPUX_THREADS -D_HPUX_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_REENTRANT"
                # +ESdbgasm only valid on bundled cc on RISC
                # silently ignored for ia64
@@ -275,7 +264,6 @@ case "$host" in
                use_sigposix=yes
                ;;
        *-*-solaris*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -DGC_SOLARIS_THREADS -DGC_SOLARIS_PTHREADS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_MMAP -DUSE_MUNMAP -DPLATFORM_SOLARIS"
                need_link_unlink=yes
                libmono_cflags="-D_REENTRANT"
@@ -288,8 +276,7 @@ case "$host" in
                ;;
        *-*-darwin*)
                parallel_mark="Disabled_Currently_Hangs_On_MacOSX"
-               host_win32=no
-               platform_darwin=yes
+               host_darwin=yes
                target_mach=yes
                CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_MACOSX_THREADS -DPLATFORM_MACOSX -DUSE_MMAP -DUSE_MUNMAP"
                libmono_cflags="-D_THREAD_SAFE"
@@ -327,7 +314,6 @@ case "$host" in
                esac
                ;;
        *-*-haiku*)
-               host_win32=no
                CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_THREAD_SAFE"
                libmono_cflags="-D_REENTRANT -D_THREAD_SAFE"
                libdl=
@@ -339,7 +325,6 @@ case "$host" in
                ;;
        *)
                AC_MSG_WARN([*** Please add $host to configure.ac checks!])
-               host_win32=no
                libdl="-ldl"
                ;;
 esac
@@ -360,9 +345,8 @@ fi
 AC_SUBST(extra_runtime_ldflags)
 AM_CONDITIONAL(HOST_WIN32, test x$host_win32 = xyes)
 AM_CONDITIONAL(TARGET_WIN32, test x$target_win32 = xyes)
-AM_CONDITIONAL(PLATFORM_GNU, echo x$target_os | grep -q -- -gnu)
 AM_CONDITIONAL(PLATFORM_LINUX, echo x$target_os | grep -q linux)
-AM_CONDITIONAL(PLATFORM_DARWIN, test x$platform_darwin = xyes)
+AM_CONDITIONAL(PLATFORM_DARWIN, test x$host_darwin = xyes)
 AM_CONDITIONAL(PLATFORM_SIGPOSIX, test x$use_sigposix = xyes)
 AM_CONDITIONAL(PLATFORM_ANDROID, test x$platform_android = xyes)
 
@@ -667,17 +651,9 @@ AC_CONFIG_SUBDIRS(eglib)
 
 GLIB_CFLAGS='-I$(top_srcdir)/eglib/src -I$(top_builddir)/eglib/src'
 GLIB_LIBS='-L$(top_builddir)/eglib/src -leglib -lm'
-BUILD_GLIB_CFLAGS="$GLIB_CFLAGS"
-BUILD_GLIB_LIBS="$GLIB_LIBS"
-GMODULE_CFLAGS="$GLIB_CFLAGS"
-GMODULE_LIBS="$GLIB_LIBS"
   
 AC_SUBST(GLIB_CFLAGS)
 AC_SUBST(GLIB_LIBS)
-AC_SUBST(GMODULE_CFLAGS)
-AC_SUBST(GMODULE_LIBS)
-AC_SUBST(BUILD_GLIB_CFLAGS)
-AC_SUBST(BUILD_GLIB_LIBS)
 
 # Enable support for fast thread-local storage
 # Some systems have broken support, so we allow to disable it.
@@ -953,12 +929,6 @@ if test x$has_extension_module != xno ; then
        AC_MSG_NOTICE([Enabling mono extension module.])
 fi
 
-AC_ARG_ENABLE(gsharing, [  --enable-gsharing Enable gsharing], enable_gsharing=$enableval, enable_gsharing=no)
-if test x$enable_gsharing = xyes; then
-       AC_DEFINE(ENABLE_GSHAREDVT,1,[Gsharing])
-fi
-
-# A synonym
 AC_ARG_ENABLE(gsharedvt, [  --enable-gsharedvt Enable generic valuetype sharing], enable_gsharedvt=$enableval, enable_gsharedvt=no)
 if test x$enable_gsharedvt = xyes; then
        AC_DEFINE(ENABLE_GSHAREDVT,1,[Gsharedvt])
@@ -1941,7 +1911,7 @@ if test x$host_win32 = xno; then
        dnl * back 
        dnl **************************************
        if test "x$havekqueue" = "xyes" -a "x$ac_cv_header_sys_event_h" = "xyes"; then
-               if test "x$platform_darwin" = "xno"; then
+               if test "x$host_darwin" = "xno"; then
                        AC_DEFINE(USE_KQUEUE_FOR_THREADPOOL, 1, [Use kqueue for the threadpool])
                fi
        fi
@@ -2101,6 +2071,7 @@ if test x$host_win32 = xno; then
        AC_CHECK_FUNCS(readv writev preadv pwritev)
        AC_CHECK_FUNCS(setpgid)
        AC_CHECK_FUNCS(system)
+       AC_CHECK_FUNCS(fork execv execve)
        AC_CHECK_SIZEOF(size_t)
        AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], , 
                [#include <sys/types.h>
@@ -2117,6 +2088,8 @@ if test x$host_win32 = xno; then
                 #include <fcntl.h>])
        AC_CHECK_TYPES([struct iovec], [AC_DEFINE(HAVE_STRUCT_IOVEC)], ,
                [#include <sys/uio.h>])
+       AC_CHECK_TYPES([struct linger], [AC_DEFINE(HAVE_STRUCT_LINGER)], ,
+               [#include <sys/socket.h>])
        AC_CHECK_TYPES([struct pollfd], [AC_DEFINE(HAVE_STRUCT_POLLFD)], ,
                [#include <sys/poll.h>])
        AC_CHECK_TYPES([struct stat], [AC_DEFINE(HAVE_STRUCT_STAT)], ,
@@ -2189,10 +2162,6 @@ if test x$host_win32 = xno; then
         #endif
        ])
        AC_CHECK_HEADERS([termios.h])
-
-       dnl * This is provided in io-layer, but on windows it's only available
-       dnl * on xp+
-       AC_DEFINE(HAVE_GETPROCESSID, 1, [Define if GetProcessId is available])
 else
        dnl *********************************
        dnl *** Checks for Windows compilation ***
@@ -2351,16 +2320,6 @@ else
        AC_CHECK_DECLS(InterlockedAdd, [], [], [[#include <windows.h>]])
        AC_CHECK_DECLS(InterlockedAdd64, [], [], [[#include <windows.h>]])
        AC_CHECK_DECLS(__readfsdword, [], [], [[#include <windows.h>]])
-
-       AC_MSG_CHECKING(for GetProcessId)
-       AC_TRY_COMPILE([#include <windows.h>], [
-               GetProcessId (0);
-       ], [
-          AC_MSG_RESULT(yes)
-          AC_DEFINE(HAVE_GETPROCESSID)
-       ], [
-          AC_MSG_RESULT(no)
-       ])
 fi
 
 dnl socklen_t check
@@ -2405,8 +2364,6 @@ if test "x$ac_cv_truncl" != "xyes"; then
    AC_CHECK_LIB(sunmath, aintl, [ AC_DEFINE(HAVE_AINTL, 1, [Has the 'aintl' function]) LIBS="$LIBS -lsunmath"])
 fi
 
-AC_CHECK_FUNCS(round)
-AC_CHECK_FUNCS(rint)
 AC_CHECK_FUNCS(execvp)
 
 dnl ****************************
@@ -2728,13 +2685,11 @@ XINERAMA="libXinerama.so.1"
 sizeof_register="SIZEOF_VOID_P"
 
 jit_wanted=true
-sgen_supported=false
 boehm_supported=true
 case "$host" in
        mips*)
                TARGET=MIPS;
                arch_target=mips;
-               sgen_supported=true
                ACCESS_UNALIGNED="no"
 
                AC_MSG_CHECKING(for mips n32)
@@ -2773,25 +2728,20 @@ case "$host" in
                        # foo.c:6: warning: visibility attribute not supported in this configuration; ignored
                        # ld: fatal: relocation error: R_386_GOTOFF: file /var/tmp//ccxYR96k.o: symbol astruct: relocation must bind locally
                        have_visibility_hidden=no
-                       sgen_supported=true
                        ;;
                  mingw*|cygwin*)
-                       sgen_supported=true
                        have_visibility_hidden=no                 
                        ;;
                  haiku*)
                        LIBC=libroot.so
                        ;;
                  linux*)
-                       sgen_supported=true
                        AOT_SUPPORTED="yes"
                        ;;
                  darwin*)
-                       sgen_supported=true
                        AOT_SUPPORTED="yes"
                        ;;
                  openbsd*|freebsd*|kfreebsd-gnu*)
-                       sgen_supported=true
                        ;;
                esac
                ;;
@@ -2804,18 +2754,14 @@ case "$host" in
                fi
                case $host_os in
                  linux*)
-                       sgen_supported=true
                        AOT_SUPPORTED="yes"
                        ;;
                  darwin*)
-                       sgen_supported=true
                        AOT_SUPPORTED="yes"
                        ;;
                  openbsd*|freebsd*|kfreebsd-gnu*)
-                       sgen_supported=true
                        ;;
                  mingw*)
-                       sgen_supported=true
                        ;;
                esac
                case "$host" in
@@ -2855,7 +2801,6 @@ case "$host" in
                if test x"$AR" = xfalse; then
                        AC_MSG_ERROR([The required utility 'ar' is not found in your PATH. Usually it can be found in /usr/ccs/bin.])
                fi
-               sgen_supported=true
                ;;
        *-mingw*|*-*-cygwin*)
                # When this is enabled, it leads to very strange crashes at runtime (gcc-3.4.4)
@@ -2875,22 +2820,27 @@ case "$host" in
                arch_target=ppc;
                case $host_os in
                  linux*|darwin*)
-                       sgen_supported=true
                        ;;
                esac
                ;;
+       armv7k-*-darwin*)
+               TARGET=ARM;
+               TARGET_SYS=WATCHOS
+               arch_target=arm;
+               ACCESS_UNALIGNED="no"
+               CPPFLAGS="$CPPFLAGS -D__ARM_EABI__"
+               ;;
+
        arm*-darwin*)
                TARGET=ARM;
                arch_target=arm;
                ACCESS_UNALIGNED="no"
                CPPFLAGS="$CPPFLAGS -D__ARM_EABI__"
-               sgen_supported=true
                ;;
        arm*-linux*)
                TARGET=ARM;
                arch_target=arm;
                ACCESS_UNALIGNED="no"
-               sgen_supported=true
                AOT_SUPPORTED="yes"
                CPPFLAGS="$CPPFLAGS -D__ARM_EABI__"
                ;;
@@ -2899,21 +2849,18 @@ case "$host" in
 #              TARGET=ARM;
 #              arch_target=arm;
 #              ACCESS_UNALIGNED="no"
-#              sgen_supported=true
 #              AOT_SUPPORTED="no"
 #              ;;
        aarch64-*)
                # https://lkml.org/lkml/2012/7/15/133
                TARGET=ARM64
                arch_target=arm64
-               sgen_supported=true
                boehm_supported=false
                ;;
        s390x-*-linux*)
                TARGET=S390X;
                arch_target=s390x;
                ACCESS_UNALIGNED="yes"
-               sgen_supported=true
                CFLAGS="$CFLAGS -mbackchain -D__USE_STRING_INLINES"
                ;;
 esac
@@ -2932,6 +2879,11 @@ if test "x$host" != "x$target"; then
                # Can't use tls, since it depends on the runtime detection of tls offsets
                # in mono-compiler.h
                with_tls=pthread
+               case "$target" in
+               armv7k-*)
+                       AC_DEFINE(TARGET_WATCHOS, 1, [...])
+                       ;;
+               esac            
                ;;
    powerpc64-ps3-linux-gnu)
                TARGET=POWERPC64
@@ -3012,7 +2964,6 @@ if test "x$host" != "x$target"; then
                AC_DEFINE(TARGET_X86, 1, [...])
                AC_DEFINE(TARGET_ANDROID, 1, [...])
                CPPFLAGS="$CPPFLAGS"
-               sgen_supported=true
                # Can't use tls, since it depends on the runtime detection of tls offsets
                # in mono-compiler.h            
                with_tls=pthread
@@ -3024,7 +2975,6 @@ if test "x$host" != "x$target"; then
                AC_DEFINE(TARGET_AMD64, 1, [...])
                AC_DEFINE(TARGET_ANDROID, 1, [...])
                CPPFLAGS="$CPPFLAGS"
-               sgen_supported=true
                # Can't use tls, since it depends on the runtime detection of tls offsets
                # in mono-compiler.h
                with_tls=pthread
@@ -3036,7 +2986,6 @@ if test "x$host" != "x$target"; then
                AC_DEFINE(TARGET_AMD64, 1, [...])
                AC_DEFINE(TARGET_PS4, 1, [...])
                CPPFLAGS="$CPPFLAGS"
-               sgen_supported=true
                # Can't use tls, since it depends on the runtime detection of tls offsets
                # in mono-compiler.h
                with_tls=pthread
@@ -3149,7 +3098,12 @@ if test x$GCC = "xyes"; then
 fi
 
 if test "x$target_mach" = "xyes"; then
-   if test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64"; then
+
+   if test "x$TARGET_SYS" = "xWATCHOS"; then
+         AC_DEFINE(TARGET_WATCHOS,1,[The JIT/AOT targets WatchOS])
+         CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_WATCHOS"
+         CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_WATCHOS"
+   elif test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64"; then
          AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS])
          CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS"
          CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_IOS"
@@ -3199,21 +3153,11 @@ fi
 dnl 
 dnl Simple Generational checks (sgen)
 dnl
-if $sgen_supported; then
-   build_sgen_default=yes
-else
-   build_sgen_default=no
-fi
 SGEN_DEFINES=
-AC_ARG_WITH(sgen, [  --with-sgen=yes,no             Extra Generational GC, default=yes],[buildsgen=$with_sgen],[buildsgen=$build_sgen_default])
+AC_ARG_WITH(sgen, [  --with-sgen=yes,no             Extra Generational GC, default=yes],[buildsgen=$with_sgen],[buildsgen=yes])
 if test x$buildsgen = xyes; then
-   if $sgen_supported; then
-       SGEN_DEFINES="-DHAVE_SGEN_GC -DHAVE_MOVING_COLLECTOR"
-       gc_msg="sgen and $gc_msg"
-   else
-       buildsgen=no
-       AC_MSG_WARN("Sgen is not supported on this platform")
-   fi
+   SGEN_DEFINES="-DHAVE_SGEN_GC -DHAVE_MOVING_COLLECTOR"
+   gc_msg="sgen and $gc_msg"
 fi
 AC_SUBST(SGEN_DEFINES)
 AM_CONDITIONAL(SUPPORT_SGEN, test x$buildsgen = xyes)
@@ -3359,7 +3303,7 @@ if test ${TARGET} = ARM; then
        fpu=NONE
 
        # iOS GCC always uses the 'softfp' ABI.
-       if test x"$GCC" = xyes && test x$platform_darwin = xyes; then
+       if test x"$GCC" = xyes && test x$host_darwin = xyes; then
                fpu=VFP
        fi
 
@@ -3493,10 +3437,11 @@ case "x$libgc" in
                ;;
 esac
 
-AC_ARG_WITH(profile4_x,[  --with-profile4=yes,no          If you want to install the 4.6 FX (defaults to yes)],                [], [with_profile4_x=yes])
-AC_ARG_WITH(monodroid, [  --with-monodroid=yes,no         If you want to build the MonoDroid assemblies (defaults to no)],     [], [with_monodroid=no])
-AC_ARG_WITH(monotouch, [  --with-monotouch=yes,no         If you want to build the Xamarin.iOS assemblies (defaults to no)],   [], [with_monotouch=no])
-AC_ARG_WITH(xammac,    [  --with-xammac=yes,no            If you want to build the Xamarin.Mac assemblies (defaults to no)],   [], [with_xammac=no])
+AC_ARG_WITH(profile4_x,      [  --with-profile4=yes,no          If you want to install the 4.6 FX (defaults to yes)],                 [], [with_profile4_x=yes])
+AC_ARG_WITH(monodroid,       [  --with-monodroid=yes,no         If you want to build the MonoDroid assemblies (defaults to no)],      [], [with_monodroid=no])
+AC_ARG_WITH(monotouch,       [  --with-monotouch=yes,no         If you want to build the Xamarin.iOS assemblies (defaults to no)],    [], [with_monotouch=no])
+AC_ARG_WITH(monotouch_watch, [  --with-monotouch_watch=yes,no   If you want to build the Xamarin.WatchOS assemblies (defaults to no)],[], [with_monotouch_watch=no])
+AC_ARG_WITH(xammac,          [  --with-xammac=yes,no            If you want to build the Xamarin.Mac assemblies (defaults to no)],    [], [with_xammac=no])
 
 OPROFILE=no
 AC_ARG_WITH(oprofile,[  --with-oprofile=no,<oprofile install dir>   Enable oprofile support (defaults to no)],[
@@ -3543,6 +3488,13 @@ AC_ARG_WITH(cooperative_gc, [  --with-cooperative-gc=yes|no      Enable cooperat
        fi
 ], [with_cooperative_gc=no])
 
+AC_ARG_WITH(checked_build, [  --with-checked-build=yes|no      Enable checked build (expensive asserts)) (defaults to no)],[
+       if test x$with_checked_build != xno ; then
+               AC_DEFINE(CHECKED_BUILD,1,[Enable checked build.])
+       fi
+], [with_checked_build=no])
+
+
 AC_CHECK_HEADER([malloc.h], 
                [AC_DEFINE([HAVE_USR_INCLUDE_MALLOC_H], [1], 
                        [Define to 1 if you have /usr/include/malloc.h.])],,)
@@ -3576,6 +3528,7 @@ if test x$cross_compiling = xyes -o x$enable_mcs_build = xno; then
    with_profile4_x=no
    with_monodroid=no
    with_monotouch=no
+   with_monotouch_watch=no
    with_xammac=no
 fi
 
@@ -3598,6 +3551,7 @@ libmono_ldflags="$libmono_ldflags $LIBS"
 AM_CONDITIONAL(INSTALL_4_x, [test "x$with_profile4_x" = xyes])
 AM_CONDITIONAL(INSTALL_MONODROID, [test "x$with_monodroid" != "xno"])
 AM_CONDITIONAL(INSTALL_MONOTOUCH, [test "x$with_monotouch" != "xno"])
+AM_CONDITIONAL(INSTALL_MONOTOUCH_WATCH, [test "x$with_monotouch_watch" != "xno"])
 AM_CONDITIONAL(INSTALL_XAMMAC, [test "x$with_xammac" != "xno"])
 
 AM_CONDITIONAL(MIPS_GCC, test ${TARGET}${ac_cv_prog_gcc} = MIPSyes)
@@ -3915,7 +3869,7 @@ if test x$host_win32 = xyes; then
    sed -e "s,-mno-cygwin,,g" libtool > libtool.new; mv libtool.new libtool; chmod 755 libtool
 fi
 
-if test x$platform_darwin = xyes; then
+if test x$host_darwin = xyes; then
    # This doesn't seem to be required and it slows down parallel builds
    sed -e 's,lock_old_archive_extraction=yes,lock_old_archive_extraction=no,g' < libtool > libtool.new && mv libtool.new libtool && chmod +x libtool
 fi
@@ -3964,7 +3918,7 @@ fi
 
     echo "MONO_VERSION = $myver" >> $mcs_topdir/build/config.make
 
-    if test x$platform_darwin = xyes; then
+    if test x$host_darwin = xyes; then
       echo "PLATFORM = darwin" >> $mcs_topdir/build/config.make
     fi
 
@@ -4012,13 +3966,14 @@ echo "
        LLVM Back End: $enable_llvm (dynamically loaded: $enable_loadedllvm)
 
    Libraries:
-       .NET 4.6:      $with_profile4_x
-       MonoDroid:     $with_monodroid
-       MonoTouch:     $with_monotouch
-       Xamarin.Mac:   $with_xammac
-       JNI support:   $jdk_headers_found
-       libgdiplus:    $libgdiplus_msg
-       zlib:          $zlib_msg
+       .NET 4.6:        $with_profile4_x
+       MonoDroid:       $with_monodroid
+       Xamarin.iOS:     $with_monotouch
+       Xamarin.WatchOS: $with_monotouch_watch
+       Xamarin.Mac:     $with_xammac
+       JNI support:     $jdk_headers_found
+       libgdiplus:      $libgdiplus_msg
+       zlib:            $zlib_msg
        $disabled
 "
 if test x$with_static_mono = xno -a "x$host_win32" != "xyes"; then
index 5281419c00bcffd42155da17f705895cd7232e29..9d094ea7cdfaef28532cc71d1d167c34141178ce 100644 (file)
@@ -136,6 +136,7 @@ AC_CHECK_SIZEOF(long)
 AC_CHECK_SIZEOF(long long)
 AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf)
 AC_CHECK_FUNCS(getrlimit)
+AC_CHECK_FUNCS(fork execv execve)
 
 #
 # Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding
@@ -150,7 +151,7 @@ elif test x$target_ios = xno; then
 AC_CHECK_FUNCS(strndup getpwuid_r)
 fi
 
-AM_CONDITIONAL(NEED_VASPRINTF, test x$have_vasprintf = x )
+AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = x )
 AM_ICONV()
 AC_SEARCH_LIBS(sqrtf, m)
 
index 70d519ea225ca26dfef7cb1376125b8c07552204..31771dfd9a19dab5f0af901207d869f5160264b2 100644 (file)
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES = libeglib.la libeglib-static.la
+noinst_LTLIBRARIES = libeglib.la
 
 AM_CFLAGS = $(WERROR_CFLAGS)
 
@@ -59,8 +59,6 @@ libeglib_la_SOURCES = \
        $(vasprintf_files)
 
 libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2
-libeglib_static_la_SOURCES=$(libeglib_la_SOURCES)
-libeglib_static_la_CFLAGS = $(libeglib_la_CFLAGS)
 
 AM_CPPFLAGS = -I$(srcdir)
 
@@ -72,9 +70,6 @@ libeglib_la_LIBADD = -llog
 endif
 endif
 
-libeglib_static_la_LIBADD = $(libeglib_la_LIBADD) $(LIBICONV)
-libeglib_static_la_LDFLAGS = -static
-
 MAINTAINERCLEANFILES = Makefile.in
 
 EXTRA_DIST = eglib-config.h.in $(win_files) $(unix_files)
index a01904e3e3440cffe35c1ce0383382d9e8ceb227..4d0bf9e8eca919c44d609095fef62b01ada0f9a9 100644 (file)
@@ -248,6 +248,9 @@ g_spawn_command_line_sync (const gchar *command_line,
                                GError **error)
 {
 #ifdef G_OS_WIN32
+#elif !defined (HAVE_FORK) || !defined (HAVE_EXECV)
+       fprintf (stderr, "g_spawn_command_line_sync not supported on this platform\n");
+       return FALSE;
 #else
        pid_t pid;
        gchar **argv;
@@ -344,6 +347,9 @@ g_spawn_async_with_pipes (const gchar *working_directory,
                        GError **error)
 {
 #ifdef G_OS_WIN32
+#elif !defined (HAVE_FORK) || !defined (HAVE_EXECVE)
+       fprintf (stderr, "g_spawn_async_with_pipes is not supported on this platform\n");
+       return FALSE;
 #else
        pid_t pid;
        int info_pipe [2];
index c3a9000f8d225839522e6dfad8a9d8d4e08f82a1..e6f4b925b61c0eeb2b063a5c686ca7941fd0d0d5 100644 (file)
@@ -219,10 +219,10 @@ g_get_charset (G_CONST_RETURN char **charset)
                is_utf8 = FALSE;
 #else
                /* These shouldn't be heap allocated */
-#if HAVE_LOCALCHARSET_H
-               my_charset = locale_charset ();
-#elif defined(HAVE_LANGINFO_H)
+#if defined(HAVE_LANGINFO_H)
                my_charset = nl_langinfo (CODESET);
+#elif defined(HAVE_LOCALCHARSET_H)
+               my_charset = locale_charset ();
 #else
                my_charset = "UTF-8";
 #endif
index dab43d5cf4bf3b8b9a5b5f8cb175dee38a5fe69f..d6b00edf218008ecd8cfe90bc66b9b607431428f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit dab43d5cf4bf3b8b9a5b5f8cb175dee38a5fe69f
+Subproject commit d6b00edf218008ecd8cfe90bc66b9b607431428f
index 3976a6088118b35ed318f8e78767066cb78ffdf9..a09accbcb9771db77a3b0370c954f643d59f4ce7 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 3976a6088118b35ed318f8e78767066cb78ffdf9
+Subproject commit a09accbcb9771db77a3b0370c954f643d59f4ce7
index a916688137c5acd05967a4e7c7b02e2b785d46eb..4f391fe60cbd36f3b3528e05a45d81ee60f390d8 100644 (file)
@@ -1,9 +1,9 @@
 
-AM_CPPFLAGS = $(GMODULE_CFLAGS)
+AM_CPPFLAGS = $(GLIB_CFLAGS)
 
 lib_LTLIBRARIES = libikvm-native.la
 
 libikvm_native_la_SOURCES = jni.c os.c jni.h
 
 libikvm_native_la_LDFLAGS = -avoid-version
-libikvm_native_la_LIBADD = $(GMODULE_LIBS)
+libikvm_native_la_LIBADD = $(GLIB_LIBS)
index 4ea4eb1da3038752a477a5ae95e17cf26ce0f9ce..3a449bf96814ab9c1666ba2f1a98d6c9c45b401d 100644 (file)
@@ -1,4 +1,4 @@
-include $(topdir)/build/profiles/net_4_5.make
+include $(topdir)/build/profiles/net_4_x.make
 PROFILE_MCS_FLAGS += -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5
 XAMMAC_4_5=1
 NO_WINDOWS_BASE=1
index 8545b270aafc560e14d67f2be08490b0c6dda7d6..b975e9699ea8fb53a4ce56c332bc4631ee4ea7f3 100644 (file)
@@ -16,7 +16,7 @@ monotouch_SUBDIRS = System.Collections.Concurrent System.Collections System.Comp
        System.Diagnostics.Process System.Diagnostics.TextWriterTraceListener System.Diagnostics.TraceEvent System.Diagnostics.TraceSource System.Globalization.Calendars \
        System.IO.Compression System.IO.Compression.ZipFile System.IO.FileSystem System.IO.FileSystem.DriveInfo System.IO.FileSystem.Primitives \
        System.IO.IsolatedStorage System.IO.MemoryMappedFiles System.IO.UnmanagedMemoryStream System.Net.AuthenticationManager System.Net.Cache \
-       System.Net.Http.WebRequestHandler System.Net.HttpListener System.Net.Mail System.Net.NameResolution System.Net.Security System.Net.ServicePoint System.Net.Sockets \
+       System.Net.HttpListener System.Net.Mail System.Net.NameResolution System.Net.Security System.Net.ServicePoint System.Net.Sockets \
        System.Net.Utilities System.Net.WebHeaderCollection System.Net.WebSockets System.Net.WebSockets.Client System.Resources.ReaderWriter System.Runtime.CompilerServices.VisualC \
        System.Security.AccessControl System.Security.Claims System.Security.Cryptography.DeriveBytes System.Security.Cryptography.Encoding System.Security.Cryptography.Encryption \
        System.Security.Cryptography.Encryption.Aes System.Security.Cryptography.Encryption.ECDiffieHellman System.Security.Cryptography.Encryption.ECDsa System.Security.Cryptography.Hashing \
@@ -31,12 +31,12 @@ reflection_SUBDIRS = System.Reflection.Emit.ILGeneration System.Reflection.Emit.
 mobile_static_SUBDIRS = $(monotouch_SUBDIRS)
 
 net_4_5_SUBDIRS = $(monotouch_SUBDIRS) $(reflection_SUBDIRS) System.Diagnostics.PerformanceCounter \
-       System.IO.FileSystem.Watcher System.IO.Pipes System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController 
+       System.IO.FileSystem.Watcher System.IO.Pipes System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.Net.Http.WebRequestHandler
 
 monodroid_SUBDIRS = $(monotouch_SUBDIRS) $(reflection_SUBDIRS)
 
-xammac_SUBDIRS = $(net_4_5_SUBDIRS)
-xammac_net_4_5_SUBDIRS = $(net_4_5_SUBDIRS)
+xammac_SUBDIRS = $(monotouch_SUBDIRS)
+xammac_net_4_5_SUBDIRS = $(monotouch_SUBDIRS) $(reflection_SUBDIRS)
 
 monotouch_watch_SUBDIRS = $(monotouch_SUBDIRS)
 
index 3b1a3929a8421c7b216ba575c672b559f4363bb1..89df05537785702076e7b0b9a3cf1831880c4e92 100644 (file)
@@ -20,7 +20,7 @@
 // THE SOFTWARE.
 // 
 
-#if !MOBILE
+#if !MOBILE && !XAMMAC_4_5
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.CallbackBehaviorAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexChannelFactory<>))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexClientBase<>))]
index 41b9ff38adac1c052d90f694460a8ac9bc47fd8a..a80d1c6fd126c5c9ffc8e0b8923fd9805bb0910e 100644 (file)
@@ -20,7 +20,7 @@
 // THE SOFTWARE.
 // 
 
-#if !MOBILE
+#if !MOBILE && !XAMMAC_4_5
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.ConnectionOrientedTransportBindingElement))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SslStreamSecurityBindingElement))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.TcpConnectionPoolSettings))]
index 09aa79c3d88d6caf1774a6b7f6f731dcc9b3e630..3e336f985322c2432cac9a767a64a41f79cdf98b 100644 (file)
@@ -46,6 +46,8 @@ mobile_common_dirs := \
        System.ComponentModel.DataAnnotations \
        System.ComponentModel.Composition.4.5 \
        System.Net \
+       System.Net.Http \
+       System.Net.Http.WebRequest      \
        System.Windows \
        System.Xml.Serialization \
        Mono.CSharp     \
@@ -59,8 +61,6 @@ mobile_static_dirs := \
 mobile_dynamic_dirs := \
        $(mobile_common_dirs)   \
        Mono.CompilerServices.SymbolWriter      \
-       System.Net.Http \
-       System.Net.Http.WebRequest      \
        $(pcl_facade_dirs)
 
 xammac_dirs := \
index 57352e70f4f287d3fea971795266fd008039e9eb..f663120bf798730223c944db359caa7873771dc5 100644 (file)
@@ -472,7 +472,7 @@ namespace Microsoft.Build.BuildEngine {
 
                        BuildItemGroup big;                     
                        BuildItem bi = new BuildItem (this);
-                       bi.finalItemSpec = ((ITaskItem2)taskitem).EvaluatedIncludeEscaped;
+                       bi.finalItemSpec = taskitem.ItemSpec;
 
                        foreach (DictionaryEntry de in taskitem.CloneCustomMetadata ()) {
                                bi.unevaluatedMetadata.Add ((string) de.Key, (string) de.Value);
index 536204e94fef828b98836d56953377718b88a22b..ccfc0fa3a0ea8a46c1a5018af0732e84820892b4 100644 (file)
@@ -156,7 +156,7 @@ namespace Microsoft.Build.BuildEngine {
                        for (int i = 0; i < lists.Count; i++) {
                                foreach (object o in lists [i]) {
                                        if (o is string)
-                                               expressionCollection.Add ((string) o);
+                                               expressionCollection.Add (MSBuildUtils.Unescape ((string) o));
                                        else if (!allowItems && o is ItemReference)
                                                expressionCollection.Add (((ItemReference) o).OriginalString);
                                        else if (!allowMd && o is MetadataReference) {
index d629906633200d69b14afb6c493cff7268e19b8f..ca0034a10923b5ab756aa8c38ba1c96c82115856 100644 (file)
@@ -233,11 +233,11 @@ namespace Microsoft.Build.BuildEngine {
                        // Trim and Remove empty items
                        List<ITaskItem> toRemove = new List<ITaskItem> ();
                        for (int i = 0; i < finalItems.Count; i ++) {
-                               string s = ((ITaskItem2)finalItems [i]).EvaluatedIncludeEscaped.Trim ();
+                               string s = finalItems [i].ItemSpec.Trim ();
                                if (s.Length == 0)
                                        toRemove.Add (finalItems [i]);
                                else
-                                       ((ITaskItem2)finalItems [i]).EvaluatedIncludeEscaped = s;
+                                       finalItems [i].ItemSpec = s;
                        }
                        foreach (ITaskItem ti in toRemove)
                                finalItems.Remove (ti);
index 1aa785622ba7e91e8b9f10a9d9d3cb286d17750f..24b76b6c07c3d633162467a01cb9077bbbc96397 100644 (file)
@@ -79,6 +79,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
                                                <Message Text='Text5' Importance='normal'/>
                                                <Message Text='Text6' Importance='high'/>
                                                <Message Text='Text7' />
+                                               <Message Text='%22abc test%22 123 %22def%22' />
                                                <Message Text='Text8' Importance='weird_importance'/>
                                        </Target>
                                </Project>
@@ -102,7 +103,8 @@ namespace MonoTests.Microsoft.Build.Tasks {
                        Assert.AreEqual (0, testLogger.CheckAny ("Text5", MessageImportance.Normal), "A5");
                        Assert.AreEqual (0, testLogger.CheckAny ("Text6", MessageImportance.High), "A6");
                        Assert.AreEqual (0, testLogger.CheckAny ("Text7", MessageImportance.Normal), "A7");
-                       Assert.AreEqual (1, testLogger.CheckAny ("Text8", MessageImportance.Normal), "A8");
+                       Assert.AreEqual (0, testLogger.CheckAny ("\"abc test\" 123 \"def\"", MessageImportance.Normal), "A8");
+                       Assert.AreEqual (1, testLogger.CheckAny ("Text8", MessageImportance.Normal), "A9");
                }
        }
 }      
index 4a61015f0be8d245ee5ddfae52cb8bd4b48eb3fe..3342c003e8bf890d8df77900cb32aee9f6d3eb0f 100755 (executable)
@@ -91,6 +91,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
                }
 
                [Test]
+               [Category("NotWorking")] // this fails due to an xbuild bug, it works on MS.NET
                public void TestLineWithEscapedSemicolon ()
                {
                        string[] lines = new string[] { "abc%3Btest%3B%3B", "%3Bdef" };
@@ -101,6 +102,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
                }
 
                [Test]
+               [Category("NotWorking")] // this fails due to an xbuild bug, it works on MS.NET
                public void TestLineWithEscapedSpace ()
                {
                        string[] lines = new string[] { "  %20%20abc%20test  ", "  def%20%20" };
@@ -110,6 +112,16 @@ namespace MonoTests.Microsoft.Build.Tasks {
                        });
                }
 
+               [Test]
+               public void TestLineWithEscapedQuote ()
+               {
+                       string[] lines = new string[] { "%22abc test%22 123 %22def%22" };
+                       CreateProjectAndCheck (full_filepath, lines, false, true, delegate () {
+                               CheckFileExists (full_filepath, true);
+                               CheckLines (full_filepath, new string [] {"\"abc test\" 123 \"def\""});
+                       });
+               }
+
                [Test]
                public void TestNoOverwrite ()
                {
index 5e818caf70756dba3b45a18c8443ad9eccf03891..2d2de50cd9e6d8c4d73ab42bade65cbea2c89ff2 100644 (file)
@@ -173,7 +173,7 @@ namespace Microsoft.Build.Utilities
                }
                public override string ToString ()
                {
-                       return ItemSpec;
+                       return escapedItemSpec;
                }
                
                public string ItemSpec {
index a3a5376e48c330eeb01ca2ea8c0d9084e9e3ff65..d64d3055b999b36e07e8ba66aeed04a5aba275c0 100644 (file)
@@ -92,14 +92,12 @@ namespace MonoTests.Mono.Data.Sqlite {
                                                        Assert.AreEqual(dr["Company.Name"], "Test CO");
                                                        i += 2;
                                                }
-                                               Assert.IsTrue(dr.FieldCount>0);
+                                               Assert.IsTrue(dr.FieldCount>0, i.ToString ());
                                        }
-                                       if (BCL.Tests.TestRuntime.CheckSystemVersion (8, 2))
-                                               Assert.IsTrue (false, "Apple fixed bug 27864, this check can now be removed");
                                }
                        } catch (SqliteException ex) {
-
-                               if (BCL.Tests.TestRuntime.CheckSystemVersion (8, 2)) // Expected Exception on iOS 8.2+, if this does not happen anymore it means apple fixed it
+                               // Expected Exception from iOS 8.2 (broken) to 9.0 (fixed)
+                               if (BCL.Tests.TestRuntime.CheckSystemVersion (8,2) && !BCL.Tests.TestRuntime.CheckSystemVersion (9,0)) 
                                        Assert.That (ex.Message.Contains ("no such column: com.Name"));
                                else
                                        throw new AssertionException ("Unexpected Sqlite Error", ex); // This should not happen
index 02ae6814cbfcc3254b8206ce2786be062fbf3907..a35e49d0b47c2f56568ffb19c953528aa0e15c23 100644 (file)
@@ -417,7 +417,7 @@ namespace Mono.Debugger.Soft
                 * with newer runtimes, and vice versa.
                 */
                internal const int MAJOR_VERSION = 2;
-               internal const int MINOR_VERSION = 40;
+               internal const int MINOR_VERSION = 41;
 
                enum WPSuspendPolicy {
                        NONE = 0,
@@ -801,6 +801,13 @@ namespace Mono.Debugger.Soft
                                return res;
                        }
 
+                       public string ReadUTF16String () {
+                               int len = decode_int (packet, ref offset);
+                               string res = new String (Encoding.Unicode.GetChars (packet, offset, len));
+                               offset += len;
+                               return res;
+                       }
+
                        public ValueImpl ReadValue () {
                                ElementType etype = (ElementType)ReadByte ();
 
@@ -2418,7 +2425,16 @@ namespace Mono.Debugger.Soft
                 * STRINGS
                 */
                internal string String_GetValue (long id) {
-                       return SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id)).ReadString ();
+                       var r = SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id));
+
+                       bool is_utf16 = false;
+                       if (Version.AtLeast (2, 41))
+                               is_utf16 = r.ReadByte () == 1;
+
+                       if (is_utf16)
+                               return r.ReadUTF16String ();
+                       else
+                               return r.ReadString ();
                }                       
 
                internal int String_GetLength (long id) {
index d922e9e0e640b4ab9bc3f8689299c099dce6e444..645329ee98880604e4d38bf536a48ae2733c1e9f 100644 (file)
@@ -598,7 +598,7 @@ public class Tests : TestsBase, ITest2
        public static void arguments () {
                arg1 (SByte.MaxValue - 5, Byte.MaxValue - 5, true, Int16.MaxValue - 5, UInt16.MaxValue - 5, 'F', Int32.MaxValue - 5, UInt32.MaxValue - 5, Int64.MaxValue - 5, UInt64.MaxValue - 5, 1.2345f, 6.78910, new IntPtr (Int32.MaxValue - 5), new UIntPtr (UInt32.MaxValue - 5));
                int i = 42;
-               arg2 ("FOO", null, "BLA", ref i, new GClass <int> { field = 42 }, new object ());
+               arg2 ("FOO", null, "BLA", ref i, new GClass <int> { field = 42 }, new object (), '\0'.ToString () + "A");
                Tests t = new Tests () { field_i = 42, field_s = "S" };
                t.arg3 ("BLA");
        }
@@ -609,7 +609,7 @@ public class Tests : TestsBase, ITest2
        }
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
-       public static string arg2 (string s, string s3, object o, ref int i, GClass <int> gc, object o2) {
+       public static string arg2 (string s, string s3, object o, ref int i, GClass <int> gc, object o2, string s4) {
                return s + (s3 != null ? "" : "") + o + i + gc.field + o2;
        }
 
@@ -908,6 +908,10 @@ public class Tests : TestsBase, ITest2
        public void invoke2 () {
        }
 
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public void invoke3 () {
+       }
+
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public void invoke_ex () {
                invoke_ex_inner ();
index 641fefd2afe9c647385e3ad22f0e18a355ee6f2e..3c62a78ee4f20b1751753ce79842028dd874ffad 100644 (file)
@@ -2506,6 +2506,53 @@ public class DebuggerTests
                        invoke_results.Add (res);
        }
 
+       [Test]
+       public void InvokeNested () {
+               Event e = run_until ("invoke1");
+
+               MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
+               Assert.IsNotNull (m);
+               vm.SetBreakpoint (m, 0);
+
+               StackFrame frame = e.Thread.GetFrames () [0];
+               var o = frame.GetThis () as ObjectMirror;
+
+               bool failed = false;
+
+               bool finished = false;
+               object wait = new object ();
+
+               Thread t = new Thread (delegate () {
+                               try {
+                                       o.InvokeMethod (e.Thread, m, null);
+                               } catch {
+                                       failed = true;
+                               }
+                               lock (wait) {
+                                       finished = true;
+                                       Monitor.Pulse (wait);
+                               }
+                       });
+
+               t.Start ();
+
+               StackFrame invoke_frame = null;
+
+               e = GetNextEvent ();
+               Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
+
+               // Check that nested invokes are not allowed
+               AssertThrows<VMNotSuspendedException> (delegate {
+                       o.InvokeMethod (e.Thread, m, null);
+                       });
+
+               vm.Resume ();
+               lock (wait) {
+                       if (!finished)
+                               Monitor.Wait (wait);
+               }
+       }
+
        [Test]
        public void GetThreads () {
                vm.GetThreads ();
@@ -3319,6 +3366,20 @@ public class DebuggerTests
                Assert.AreEqual ("System.Exception", types [0].FullName);
        }
 
+       [Test]
+       public void String_GetValue () {
+               // Embedded nulls
+               object val;
+
+               // Reuse this test
+               var e = run_until ("arg2");
+
+               var frame = e.Thread.GetFrames () [0];
+
+               val = frame.GetArgument (6);
+               Assert.AreEqual ('\0'.ToString () + "A", (val as StringMirror).Value);
+       }
+
        [Test]
        public void String_GetChars () {
                object val;
index a7d9f70f9954a416e88e2cf320575532dc0a181a..a0c5cf12f5761423cc174f3ed89ba402a37b6265 100644 (file)
@@ -45,6 +45,7 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
   <ItemGroup>\r
     <Compile Include="Test\Mono.Unix.Native\RealTimeSignumTests.cs" />\r
+    <Compile Include="Test\Mono.Unix.Native\SocketTest.cs" />\r
     <Compile Include="Test\Mono.Unix.Native\StdlibTest.cs" />\r
     <Compile Include="Test\Mono.Unix\ReadlinkTest.cs" />\r
     <Compile Include="Test\Mono.Unix\StdioFileStreamTest.cs" />\r
index 270b0b6aee680cb64332b06638110b58a6eda18b..e2a49354a8eb43a4790567e1c361ac2a73e87856 100644 (file)
@@ -6,5 +6,7 @@ Mono.Unix/UnixMarshalTest.cs
 Mono.Unix/UnixPathTest.cs
 Mono.Unix/UnixSignalTest.cs
 Mono.Unix/UnixUserTest.cs
+Mono.Unix.Android/TestHelper.cs
 Mono.Unix.Native/RealTimeSignumTests.cs
+Mono.Unix.Native/SocketTest.cs
 Mono.Unix.Native/StdlibTest.cs
index ffa329f1b5bf3d5fa7cc75a7a6e93355b118d117..4e2613b127991263f8ba2d31fede7f7da2a99f1f 100644 (file)
@@ -17,10 +17,10 @@ namespace Mono.Unix.Native {
                //
                // Non-generated exports
                //
-
+#if !MONODROID
                [DllImport (LIB, EntryPoint="Mono_Posix_FromRealTimeSignum")]
                private static extern int FromRealTimeSignum (Int32 offset, out Int32 rval);
-
+#endif
                // convert a realtime signal to os signal
                public static int FromRealTimeSignum (RealTimeSignum sig)
                {
index d9097f8d7a3394610167957639000144950b97e6..2ac13c6677edd26437a6fc806df7cf3e12b6d027 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * This file was automatically generated by create-native-map from ../../class/lib/net_2_0/Mono.Posix.dll.
+ * This file was automatically generated by create-native-map from ./../../class/lib/net_4_x/Mono.Posix.dll.
  *
  * DO NOT MODIFY.
  */
@@ -342,6 +342,22 @@ namespace Mono.Unix.Native {
                        return ToIovec (source, out destination) == 0;
                }
 
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromLinger")]
+               private static extern int FromLinger (ref Linger source, IntPtr destination);
+
+               public static bool TryCopy (ref Linger source, IntPtr destination)
+               {
+                       return FromLinger (ref source, destination) == 0;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToLinger")]
+               private static extern int ToLinger (IntPtr source, out Linger destination);
+
+               public static bool TryCopy (IntPtr source, out Linger destination)
+               {
+                       return ToLinger (source, out destination) == 0;
+               }
+
                [DllImport (LIB, EntryPoint="Mono_Posix_FromLockType")]
                private static extern int FromLockType (LockType value, out Int16 rval);
 
@@ -406,6 +422,38 @@ namespace Mono.Unix.Native {
                        return rval;
                }
 
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromMessageFlags")]
+               private static extern int FromMessageFlags (MessageFlags value, out Int32 rval);
+
+               public static bool TryFromMessageFlags (MessageFlags value, out Int32 rval)
+               {
+                       return FromMessageFlags (value, out rval) == 0;
+               }
+
+               public static Int32 FromMessageFlags (MessageFlags value)
+               {
+                       Int32 rval;
+                       if (FromMessageFlags (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToMessageFlags")]
+               private static extern int ToMessageFlags (Int32 value, out MessageFlags rval);
+
+               public static bool TryToMessageFlags (Int32 value, out MessageFlags rval)
+               {
+                       return ToMessageFlags (value, out rval) == 0;
+               }
+
+               public static MessageFlags ToMessageFlags (Int32 value)
+               {
+                       MessageFlags rval;
+                       if (ToMessageFlags (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
                [DllImport (LIB, EntryPoint="Mono_Posix_FromMlockallFlags")]
                private static extern int FromMlockallFlags (MlockallFlags value, out Int32 rval);
 
@@ -806,6 +854,38 @@ namespace Mono.Unix.Native {
                        return rval;
                }
 
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromShutdownOption")]
+               private static extern int FromShutdownOption (ShutdownOption value, out Int32 rval);
+
+               public static bool TryFromShutdownOption (ShutdownOption value, out Int32 rval)
+               {
+                       return FromShutdownOption (value, out rval) == 0;
+               }
+
+               public static Int32 FromShutdownOption (ShutdownOption value)
+               {
+                       Int32 rval;
+                       if (FromShutdownOption (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToShutdownOption")]
+               private static extern int ToShutdownOption (Int32 value, out ShutdownOption rval);
+
+               public static bool TryToShutdownOption (Int32 value, out ShutdownOption rval)
+               {
+                       return ToShutdownOption (value, out rval) == 0;
+               }
+
+               public static ShutdownOption ToShutdownOption (Int32 value)
+               {
+                       ShutdownOption rval;
+                       if (ToShutdownOption (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
                [DllImport (LIB, EntryPoint="Mono_Posix_FromSignum")]
                private static extern int FromSignum (Signum value, out Int32 rval);
 
@@ -1014,6 +1094,166 @@ namespace Mono.Unix.Native {
                        return ToTimezone (source, out destination) == 0;
                }
 
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixAddressFamily")]
+               private static extern int FromUnixAddressFamily (UnixAddressFamily value, out Int32 rval);
+
+               public static bool TryFromUnixAddressFamily (UnixAddressFamily value, out Int32 rval)
+               {
+                       return FromUnixAddressFamily (value, out rval) == 0;
+               }
+
+               public static Int32 FromUnixAddressFamily (UnixAddressFamily value)
+               {
+                       Int32 rval;
+                       if (FromUnixAddressFamily (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixAddressFamily")]
+               private static extern int ToUnixAddressFamily (Int32 value, out UnixAddressFamily rval);
+
+               public static bool TryToUnixAddressFamily (Int32 value, out UnixAddressFamily rval)
+               {
+                       return ToUnixAddressFamily (value, out rval) == 0;
+               }
+
+               public static UnixAddressFamily ToUnixAddressFamily (Int32 value)
+               {
+                       UnixAddressFamily rval;
+                       if (ToUnixAddressFamily (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketFlags")]
+               private static extern int FromUnixSocketFlags (UnixSocketFlags value, out Int32 rval);
+
+               public static bool TryFromUnixSocketFlags (UnixSocketFlags value, out Int32 rval)
+               {
+                       return FromUnixSocketFlags (value, out rval) == 0;
+               }
+
+               public static Int32 FromUnixSocketFlags (UnixSocketFlags value)
+               {
+                       Int32 rval;
+                       if (FromUnixSocketFlags (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketFlags")]
+               private static extern int ToUnixSocketFlags (Int32 value, out UnixSocketFlags rval);
+
+               public static bool TryToUnixSocketFlags (Int32 value, out UnixSocketFlags rval)
+               {
+                       return ToUnixSocketFlags (value, out rval) == 0;
+               }
+
+               public static UnixSocketFlags ToUnixSocketFlags (Int32 value)
+               {
+                       UnixSocketFlags rval;
+                       if (ToUnixSocketFlags (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketOptionName")]
+               private static extern int FromUnixSocketOptionName (UnixSocketOptionName value, out Int32 rval);
+
+               public static bool TryFromUnixSocketOptionName (UnixSocketOptionName value, out Int32 rval)
+               {
+                       return FromUnixSocketOptionName (value, out rval) == 0;
+               }
+
+               public static Int32 FromUnixSocketOptionName (UnixSocketOptionName value)
+               {
+                       Int32 rval;
+                       if (FromUnixSocketOptionName (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketOptionName")]
+               private static extern int ToUnixSocketOptionName (Int32 value, out UnixSocketOptionName rval);
+
+               public static bool TryToUnixSocketOptionName (Int32 value, out UnixSocketOptionName rval)
+               {
+                       return ToUnixSocketOptionName (value, out rval) == 0;
+               }
+
+               public static UnixSocketOptionName ToUnixSocketOptionName (Int32 value)
+               {
+                       UnixSocketOptionName rval;
+                       if (ToUnixSocketOptionName (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketProtocol")]
+               private static extern int FromUnixSocketProtocol (UnixSocketProtocol value, out Int32 rval);
+
+               public static bool TryFromUnixSocketProtocol (UnixSocketProtocol value, out Int32 rval)
+               {
+                       return FromUnixSocketProtocol (value, out rval) == 0;
+               }
+
+               public static Int32 FromUnixSocketProtocol (UnixSocketProtocol value)
+               {
+                       Int32 rval;
+                       if (FromUnixSocketProtocol (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketProtocol")]
+               private static extern int ToUnixSocketProtocol (Int32 value, out UnixSocketProtocol rval);
+
+               public static bool TryToUnixSocketProtocol (Int32 value, out UnixSocketProtocol rval)
+               {
+                       return ToUnixSocketProtocol (value, out rval) == 0;
+               }
+
+               public static UnixSocketProtocol ToUnixSocketProtocol (Int32 value)
+               {
+                       UnixSocketProtocol rval;
+                       if (ToUnixSocketProtocol (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketType")]
+               private static extern int FromUnixSocketType (UnixSocketType value, out Int32 rval);
+
+               public static bool TryFromUnixSocketType (UnixSocketType value, out Int32 rval)
+               {
+                       return FromUnixSocketType (value, out rval) == 0;
+               }
+
+               public static Int32 FromUnixSocketType (UnixSocketType value)
+               {
+                       Int32 rval;
+                       if (FromUnixSocketType (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketType")]
+               private static extern int ToUnixSocketType (Int32 value, out UnixSocketType rval);
+
+               public static bool TryToUnixSocketType (Int32 value, out UnixSocketType rval)
+               {
+                       return ToUnixSocketType (value, out rval) == 0;
+               }
+
+               public static UnixSocketType ToUnixSocketType (Int32 value)
+               {
+                       UnixSocketType rval;
+                       if (ToUnixSocketType (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
                [DllImport (LIB, EntryPoint="Mono_Posix_FromUtimbuf")]
                private static extern int FromUtimbuf (ref Utimbuf source, IntPtr destination);
 
index c4ff89c0573826bf5b1b77b8f98053f071e0b0d8..8b1246e617eb839c15ca494ea28e54d4566ebeb8 100644 (file)
@@ -727,6 +727,186 @@ namespace Mono.Unix.Native {
                MREMAP_MAYMOVE = 0x1,
        }
 
+       [Map]
+       [CLSCompliant (false)]
+       public enum UnixSocketType : int {
+               SOCK_STREAM    =  1, // Byte-stream socket
+               SOCK_DGRAM     =  2, // Datagram socket
+               SOCK_RAW       =  3, // Raw protocol interface (linux specific)
+               SOCK_RDM       =  4, // Reliably-delivered messages (linux specific)
+               SOCK_SEQPACKET =  5, // Sequenced-packet socket
+               SOCK_DCCP      =  6, // Datagram Congestion Control Protocol (linux specific)
+               SOCK_PACKET    = 10, // Linux specific
+       }
+
+       [Map][Flags]
+       [CLSCompliant (false)]
+       public enum UnixSocketFlags : int {
+               SOCK_CLOEXEC  = 0x80000, /* Atomically set close-on-exec flag for the new descriptor(s). */
+               SOCK_NONBLOCK = 0x00800, /* Atomically mark descriptor(s) as non-blocking. */
+       }
+
+       [Map]
+       [CLSCompliant (false)]
+       public enum UnixSocketProtocol : int {
+               IPPROTO_ICMP    =    1, /* Internet Control Message Protocol */
+               IPPROTO_IGMP    =    2, /* Internet Group Management Protocol */
+               IPPROTO_IPIP    =    4, /* IPIP tunnels (older KA9Q tunnels use 94) */
+               IPPROTO_TCP     =    6, /* Transmission Control Protocol */
+               IPPROTO_EGP     =    8, /* Exterior Gateway Protocol */
+               IPPROTO_PUP     =   12, /* PUP protocol */
+               IPPROTO_UDP     =   17, /* User Datagram Protocol */
+               IPPROTO_IDP     =   22, /* XNS IDP protocol */
+               IPPROTO_TP      =   29, /* SO Transport Protocol Class 4 */
+               IPPROTO_DCCP    =   33, /* Datagram Congestion Control Protocol */
+               IPPROTO_IPV6    =   41, /* IPv6-in-IPv4 tunnelling */
+               IPPROTO_RSVP    =   46, /* RSVP Protocol */
+               IPPROTO_GRE     =   47, /* Cisco GRE tunnels (rfc 1701,1702) */
+               IPPROTO_ESP     =   50, /* Encapsulation Security Payload protocol */
+               IPPROTO_AH      =   51, /* Authentication Header protocol */
+               IPPROTO_MTP     =   92, /* Multicast Transport Protocol */
+               IPPROTO_BEETPH  =   94, /* IP option pseudo header for BEET */
+               IPPROTO_ENCAP   =   98, /* Encapsulation Header */
+               IPPROTO_PIM     =  103, /* Protocol Independent Multicast */
+               IPPROTO_COMP    =  108, /* Compression Header Protocol */
+               IPPROTO_SCTP    =  132, /* Stream Control Transport Protocol */
+               IPPROTO_UDPLITE =  136, /* UDP-Lite (RFC 3828) */
+               IPPROTO_RAW     =  255, /* Raw IP packets */
+
+               // Number used by linux (0) has a special meaning for socket()
+               IPPROTO_IP      = 1024, /* Dummy protocol for TCP */
+               // Number used by linux (1) clashes with IPPROTO_ICMP
+               SOL_SOCKET      = 2048, /* For setsockopt() / getsockopt(): Options to be accessed at socket level, not protocol level. */
+       }
+
+       [Map]
+       [CLSCompliant (false)]
+       public enum UnixAddressFamily : int {
+               AF_UNSPEC     =  0,  /* Unspecified. */
+               AF_UNIX       =  1,  /* Local to host (pipes and file-domain). */
+               AF_INET       =  2,  /* IP protocol family. */
+               AF_AX25       =  3,  /* Amateur Radio AX.25. */
+               AF_IPX        =  4,  /* Novell Internet Protocol. */
+               AF_APPLETALK  =  5,  /* Appletalk DDP. */
+               AF_NETROM     =  6,  /* Amateur radio NetROM. */
+               AF_BRIDGE     =  7,  /* Multiprotocol bridge. */
+               AF_ATMPVC     =  8,  /* ATM PVCs. */
+               AF_X25        =  9,  /* Reserved for X.25 project. */
+               AF_INET6      = 10,  /* IP version 6. */
+               AF_ROSE       = 11,  /* Amateur Radio X.25 PLP. */
+               AF_DECnet     = 12,  /* Reserved for DECnet project. */
+               AF_NETBEUI    = 13,  /* Reserved for 802.2LLC project. */
+               AF_SECURITY   = 14,  /* Security callback pseudo AF. */
+               AF_KEY        = 15,  /* PF_KEY key management API. */
+               AF_NETLINK    = 16,
+               AF_PACKET     = 17,  /* Packet family. */
+               AF_ASH        = 18,  /* Ash. */
+               AF_ECONET     = 19,  /* Acorn Econet. */
+               AF_ATMSVC     = 20,  /* ATM SVCs. */
+               AF_RDS        = 21,  /* RDS sockets. */
+               AF_SNA        = 22,  /* Linux SNA Project */
+               AF_IRDA       = 23,  /* IRDA sockets. */
+               AF_PPPOX      = 24,  /* PPPoX sockets. */
+               AF_WANPIPE    = 25,  /* Wanpipe API sockets. */
+               AF_LLC        = 26,  /* Linux LLC. */
+               AF_CAN        = 29,  /* Controller Area Network. */
+               AF_TIPC       = 30,  /* TIPC sockets. */
+               AF_BLUETOOTH  = 31,  /* Bluetooth sockets. */
+               AF_IUCV       = 32,  /* IUCV sockets. */
+               AF_RXRPC      = 33,  /* RxRPC sockets. */
+               AF_ISDN       = 34,  /* mISDN sockets. */
+               AF_PHONET     = 35,  /* Phonet sockets. */
+               AF_IEEE802154 = 36,  /* IEEE 802.15.4 sockets. */
+               AF_CAIF       = 37,  /* CAIF sockets. */
+               AF_ALG        = 38,  /* Algorithm sockets. */
+               AF_NFC        = 39,  /* NFC sockets. */
+               AF_VSOCK      = 40,  /* vSockets. */
+       }
+
+       [Map]
+       [CLSCompliant (false)]
+       public enum UnixSocketOptionName : int {
+               SO_DEBUG                         =  1,
+               SO_REUSEADDR                     =  2,
+               SO_TYPE                          =  3,
+               SO_ERROR                         =  4,
+               SO_DONTROUTE                     =  5,
+               SO_BROADCAST                     =  6,
+               SO_SNDBUF                        =  7,
+               SO_RCVBUF                        =  8,
+               SO_SNDBUFFORCE                   = 32,
+               SO_RCVBUFFORCE                   = 33,
+               SO_KEEPALIVE                     =  9,
+               SO_OOBINLINE                     = 10,
+               SO_NO_CHECK                      = 11,
+               SO_PRIORITY                      = 12,
+               SO_LINGER                        = 13,
+               SO_BSDCOMPAT                     = 14,
+               SO_REUSEPORT                     = 15,
+               SO_PASSCRED                      = 16,
+               SO_PEERCRED                      = 17,
+               SO_RCVLOWAT                      = 18,
+               SO_SNDLOWAT                      = 19,
+               SO_RCVTIMEO                      = 20,
+               SO_SNDTIMEO                      = 21,
+               SO_SECURITY_AUTHENTICATION       = 22,
+               SO_SECURITY_ENCRYPTION_TRANSPORT = 23,
+               SO_SECURITY_ENCRYPTION_NETWORK   = 24,
+               SO_BINDTODEVICE                  = 25,
+               SO_ATTACH_FILTER                 = 26,
+               SO_DETACH_FILTER                 = 27,
+               SO_PEERNAME                      = 28,
+               SO_TIMESTAMP                     = 29,
+               SO_ACCEPTCONN                    = 30,
+               SO_PEERSEC                       = 31,
+               SO_PASSSEC                       = 34,
+               SO_TIMESTAMPNS                   = 35,
+               SO_MARK                          = 36,
+               SO_TIMESTAMPING                  = 37,
+               SO_PROTOCOL                      = 38,
+               SO_DOMAIN                        = 39,
+               SO_RXQ_OVFL                      = 40,
+               SO_WIFI_STATUS                   = 41,
+               SO_PEEK_OFF                      = 42,
+               SO_NOFCS                         = 43,
+               SO_LOCK_FILTER                   = 44,
+               SO_SELECT_ERR_QUEUE              = 45,
+               SO_BUSY_POLL                     = 46,
+               SO_MAX_PACING_RATE               = 47,
+       }
+
+       [Flags][Map]
+       [CLSCompliant (false)]
+       public enum MessageFlags : int {
+               MSG_OOB          =       0x01, /* Process out-of-band data. */
+               MSG_PEEK         =       0x02, /* Peek at incoming messages. */
+               MSG_DONTROUTE    =       0x04, /* Don't use local routing. */
+               MSG_CTRUNC       =       0x08, /* Control data lost before delivery. */
+               MSG_PROXY        =       0x10, /* Supply or ask second address. */
+               MSG_TRUNC        =       0x20,
+               MSG_DONTWAIT     =       0x40, /* Nonblocking IO. */
+               MSG_EOR          =       0x80, /* End of record. */
+               MSG_WAITALL      =      0x100, /* Wait for a full request. */
+               MSG_FIN          =      0x200,
+               MSG_SYN          =      0x400,
+               MSG_CONFIRM      =      0x800, /* Confirm path validity. */
+               MSG_RST          =     0x1000,
+               MSG_ERRQUEUE     =     0x2000, /* Fetch message from error queue. */
+               MSG_NOSIGNAL     =     0x4000, /* Do not generate SIGPIPE. */
+               MSG_MORE         =     0x8000, /* Sender will send more. */
+               MSG_WAITFORONE   =    0x10000, /* Wait for at least one packet to return.*/
+               MSG_FASTOPEN     = 0x20000000, /* Send data in TCP SYN. */
+               MSG_CMSG_CLOEXEC = 0x40000000, /* Set close_on_exit for file descriptor received through SCM_RIGHTS. */
+       }
+
+       [Map]
+       [CLSCompliant (false)]
+       public enum ShutdownOption : int {
+               SHUT_RD   = 0x01,   /* No more receptions. */
+               SHUT_WR   = 0x02,   /* No more transmissions. */
+               SHUT_RDWR = 0x03,   /* No more receptions or transmissions. */
+       }
+
        #endregion
 
        #region Structures
@@ -1228,6 +1408,14 @@ namespace Mono.Unix.Native {
                [FieldOffset (4)]
                public ulong u64;
        }
+
+       [Map ("struct linger")]
+       [CLSCompliant (false)]
+       public struct Linger {
+               public int l_onoff;
+               public int l_linger;
+       }
+
        #endregion
 
        #region Classes
@@ -4356,6 +4544,243 @@ namespace Mono.Unix.Native {
                        return sys_pwritev (fd, iov, iov.Length, offset);
                }
                #endregion
+
+               #region <socket.h> Declarations
+               //
+               // <socket.h>
+               //
+
+               // socket(2)
+               //    int socket(int domain, int type, int protocol);
+               [DllImport (LIBC, SetLastError=true, 
+                               EntryPoint="socket")]
+               static extern int sys_socket (int domain, int type, int protocol);
+
+               public static int socket (UnixAddressFamily domain, UnixSocketType type, UnixSocketFlags flags, UnixSocketProtocol protocol)
+               {
+                       var _domain = NativeConvert.FromUnixAddressFamily (domain);
+                       var _type = NativeConvert.FromUnixSocketType (type);
+                       var _flags = NativeConvert.FromUnixSocketFlags (flags);
+                       // protocol == 0 is a special case (uses default protocol)
+                       var _protocol = protocol == 0 ? 0 : NativeConvert.FromUnixSocketProtocol (protocol);
+
+                       return sys_socket (_domain, _type | _flags, _protocol);
+               }
+
+               public static int socket (UnixAddressFamily domain, UnixSocketType type, UnixSocketProtocol protocol)
+               {
+                       return socket (domain, type, 0, protocol);
+               }
+
+               // socketpair(2)
+               //    int socketpair(int domain, int type, int protocol, int sv[2]);
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_socketpair")]
+               static extern int sys_socketpair (int domain, int type, int protocol, out int socket1, out int socket2);
+
+               public static int socketpair (UnixAddressFamily domain, UnixSocketType type, UnixSocketFlags flags, UnixSocketProtocol protocol, out int socket1, out int socket2)
+               {
+                       var _domain = NativeConvert.FromUnixAddressFamily (domain);
+                       var _type = NativeConvert.FromUnixSocketType (type);
+                       var _flags = NativeConvert.FromUnixSocketFlags (flags);
+                       // protocol == 0 is a special case (uses default protocol)
+                       var _protocol = protocol == 0 ? 0 : NativeConvert.FromUnixSocketProtocol (protocol);
+
+                       return sys_socketpair (_domain, _type | _flags, _protocol, out socket1, out socket2);
+               }
+
+               public static int socketpair (UnixAddressFamily domain, UnixSocketType type, UnixSocketProtocol protocol, out int socket1, out int socket2)
+               {
+                       return socketpair (domain, type, 0, protocol, out socket1, out socket2);
+               }
+
+               // sockatmark(2)
+               //    int sockatmark(int sockfd);
+               [DllImport (LIBC, SetLastError=true)]
+               public static extern int sockatmark (int socket);
+
+               // listen(2)
+               //    int listen(int sockfd, int backlog);
+               [DllImport (LIBC, SetLastError=true)]
+               public static extern int listen (int socket, int backlog);
+
+               // getsockopt(2)
+               //    int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_getsockopt")]
+               static extern unsafe int sys_getsockopt (int socket, int level, int option_name, void *option_value, ref long option_len);
+
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_getsockopt_timeval")]
+               static extern unsafe int sys_getsockopt_timeval (int socket, int level, int option_name, out Timeval option_value);
+
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_getsockopt_linger")]
+               static extern unsafe int sys_getsockopt_linger (int socket, int level, int option_name, out Linger option_value);
+
+               public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, void *option_value, ref long option_len)
+               {
+                       var _level = NativeConvert.FromUnixSocketProtocol (level);
+                       var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+                       return sys_getsockopt (socket, _level, _option_name, option_value, ref option_len);
+               }
+
+               public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, IntPtr option_value, ref long option_len)
+               {
+                       return getsockopt (socket, level, option_name, (void*) option_value, ref option_len);
+               }
+
+               public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, out int option_value)
+               {
+                       int value;
+                       long size = sizeof (int);
+                       int ret = getsockopt (socket, level, option_name, &value, ref size);
+                       if (ret != -1 && size != sizeof (int)) {
+                               SetLastError (Errno.EINVAL);
+                               ret = -1;
+                       }
+                       option_value = value;
+                       return ret;
+               }
+
+               public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, byte[] option_value, ref long option_len)
+               {
+                       if (option_len > (option_value == null ? 0 : option_value.Length))
+                               throw new ArgumentOutOfRangeException ("option_len", "option_len > (option_value == null ? 0 : option_value.Length)");
+                       fixed (byte* ptr = option_value)
+                               return getsockopt (socket, level, option_name, ptr, ref option_len);
+               }
+
+               public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, out Timeval option_value)
+               {
+                       var _level = NativeConvert.FromUnixSocketProtocol (level);
+                       var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+                       return sys_getsockopt_timeval (socket, _level, _option_name, out option_value);
+               }
+
+               public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, out Linger option_value)
+               {
+                       var _level = NativeConvert.FromUnixSocketProtocol (level);
+                       var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+                       return sys_getsockopt_linger (socket, _level, _option_name, out option_value);
+               }
+
+               // setsockopt(2)
+               //    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_setsockopt")]
+               static extern unsafe int sys_setsockopt (int socket, int level, int option_name, void *option_value, long option_len);
+
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_setsockopt_timeval")]
+               static extern unsafe int sys_setsockopt_timeval (int socket, int level, int option_name, ref Timeval option_value);
+
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_setsockopt_linger")]
+               static extern unsafe int sys_setsockopt_linger (int socket, int level, int option_name, ref Linger option_value);
+
+               public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, void *option_value, long option_len)
+               {
+                       var _level = NativeConvert.FromUnixSocketProtocol (level);
+                       var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+                       return sys_setsockopt (socket, _level, _option_name, option_value, option_len);
+               }
+
+               public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, IntPtr option_value, long option_len)
+               {
+                       return setsockopt (socket, level, option_name, (void*) option_value, option_len);
+               }
+
+               public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, int option_value)
+               {
+                       return setsockopt (socket, level, option_name, &option_value, sizeof (int));
+               }
+
+               public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, byte[] option_value, long option_len)
+               {
+                       if (option_len > (option_value == null ? 0 : option_value.Length))
+                               throw new ArgumentOutOfRangeException ("option_len", "option_len > (option_value == null ? 0 : option_value.Length)");
+                       fixed (byte* ptr = option_value)
+                               return setsockopt (socket, level, option_name, ptr, option_len);
+               }
+
+               public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, Timeval option_value)
+               {
+                       var _level = NativeConvert.FromUnixSocketProtocol (level);
+                       var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+                       return sys_setsockopt_timeval (socket, _level, _option_name, ref option_value);
+               }
+
+               public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, Linger option_value)
+               {
+                       var _level = NativeConvert.FromUnixSocketProtocol (level);
+                       var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+                       return sys_setsockopt_linger (socket, _level, _option_name, ref option_value);
+               }
+
+               // shutdown(2)
+               //    int shutdown(int sockfd, int how);
+               [DllImport (LIBC, SetLastError=true, 
+                               EntryPoint="shutdown")]
+               static extern int sys_shutdown (int socket, int how);
+
+               public static int shutdown (int socket, ShutdownOption how)
+               {
+                       var _how = NativeConvert.FromShutdownOption (how);
+                       return sys_shutdown (socket, _how);
+               }
+
+               // recv(2)
+               //    ssize_t recv(int sockfd, void *buf, size_t len, int flags);
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_recv")]
+               static extern unsafe long sys_recv (int socket, void *buffer, ulong length, int flags);
+
+               public static unsafe long recv (int socket, void *buffer, ulong length, MessageFlags flags)
+               {
+                       int _flags = NativeConvert.FromMessageFlags (flags);
+                       return sys_recv (socket, buffer, length, _flags);
+               }
+
+               public static unsafe long recv (int socket, IntPtr buffer, ulong length, MessageFlags flags)
+               {
+                       return recv (socket, (void*) buffer, length, flags);
+               }
+
+               public static unsafe long recv (int socket, byte[] buffer, ulong length, MessageFlags flags)
+               {
+                       if (length > (ulong) (buffer == null ? 0 : buffer.LongLength))
+                               throw new ArgumentOutOfRangeException ("length", "length > (buffer == null ? 0 : buffer.LongLength)");
+                       fixed (byte* ptr = buffer)
+                               return recv (socket, ptr, length, flags);
+               }
+
+               // send(2)
+               //    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
+               [DllImport (MPH, SetLastError=true, 
+                               EntryPoint="Mono_Posix_Syscall_send")]
+               static extern unsafe long sys_send (int socket, void *message, ulong length, int flags);
+
+               public static unsafe long send (int socket, void *message, ulong length, MessageFlags flags)
+               {
+                       int _flags = NativeConvert.FromMessageFlags (flags);
+                       return sys_send (socket, message, length, _flags);
+               }
+
+               public static unsafe long send (int socket, IntPtr message, ulong length, MessageFlags flags)
+               {
+                       return send (socket, (void*) message, length, flags);
+               }
+
+               public static unsafe long send (int socket, byte[] message, ulong length, MessageFlags flags)
+               {
+                       if (length > (ulong) (message == null ? 0 : message.LongLength))
+                               throw new ArgumentOutOfRangeException ("length", "length > (message == null ? 0 : message.LongLength)");
+                       fixed (byte* ptr = message)
+                               return send (socket, ptr, length, flags);
+               }
+
+               #endregion
        }
 
        #endregion
diff --git a/mcs/class/Mono.Posix/Test/Mono.Unix.Android/TestHelper.cs b/mcs/class/Mono.Posix/Test/Mono.Unix.Android/TestHelper.cs
new file mode 100644 (file)
index 0000000..a7a56a4
--- /dev/null
@@ -0,0 +1,12 @@
+namespace Mono.Unix.Android
+{
+       // Another version of this class is used by the Xamarin.Android test suite
+       // It is here to keep the test code #ifdef free as much as possible
+       public class TestHelper
+       {
+               public static bool CanUseRealTimeSignals ()
+               {
+                       return true;
+               }
+       }
+}
\ No newline at end of file
index 4aea4e8ba60f4db71577c3f9789c4c6333bab39f..f68fe53b8ce70b896dbb603a9530042fddae1885 100644 (file)
@@ -15,6 +15,7 @@ using System;
 using System.Text;
 using System.Threading;
 using Mono.Unix;
+using Mono.Unix.Android;
 using Mono.Unix.Native;
 
 namespace MonoTests.Mono.Unix.Native {
@@ -27,6 +28,8 @@ namespace MonoTests.Mono.Unix.Native {
                [ExpectedException (typeof (ArgumentOutOfRangeException))]
                public void TestRealTimeOutOfRange ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts = new RealTimeSignum (int.MaxValue);
                }
 
@@ -34,12 +37,16 @@ namespace MonoTests.Mono.Unix.Native {
                [ExpectedException (typeof (ArgumentOutOfRangeException))]
                public void TestRealTimeSignumNegativeOffset ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts1 = new RealTimeSignum (-1);
                }
 
                [Test]
                public void TestRTSignalEquality ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts1 = new RealTimeSignum (0);
                        RealTimeSignum rts2 = new RealTimeSignum (0);
                        Assert.That (rts1 == rts2, Is.True);
@@ -49,6 +56,8 @@ namespace MonoTests.Mono.Unix.Native {
                [Test]
                public void TestRTSignalInequality ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts1 = new RealTimeSignum (0);
                        RealTimeSignum rts2 = new RealTimeSignum (1);
                        Assert.That (rts1 == rts2, Is.False);
@@ -58,6 +67,8 @@ namespace MonoTests.Mono.Unix.Native {
                [Test]
                public void TestRTSignalGetHashCodeEquality ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts1 = new RealTimeSignum (0);
                        RealTimeSignum rts2 = new RealTimeSignum (0);
                        Assert.That (rts1.GetHashCode (), Is.EqualTo(rts2.GetHashCode ()));
@@ -66,6 +77,8 @@ namespace MonoTests.Mono.Unix.Native {
                [Test]
                public void TestRTSignalGetHashCodeInequality ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts1 = new RealTimeSignum (0);
                        RealTimeSignum rts2 = new RealTimeSignum (1);
                        Assert.That (rts1.GetHashCode (), Is.Not.EqualTo(rts2.GetHashCode ()));
@@ -74,6 +87,8 @@ namespace MonoTests.Mono.Unix.Native {
                [Test]
                public void TestIsRTSignalPropertyForRTSignum ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        UnixSignal signal1 = new UnixSignal(new RealTimeSignum (0));
                        Assert.That (signal1.IsRealTimeSignal, Is.True);
                }
@@ -81,6 +96,8 @@ namespace MonoTests.Mono.Unix.Native {
                [Test]
                public void TestIsRTSignalPropertyForSignum ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
                        Assert.That (signal1.IsRealTimeSignal, Is.False);
                }
diff --git a/mcs/class/Mono.Posix/Test/Mono.Unix.Native/SocketTest.cs b/mcs/class/Mono.Posix/Test/Mono.Unix.Native/SocketTest.cs
new file mode 100644 (file)
index 0000000..36a8d23
--- /dev/null
@@ -0,0 +1,217 @@
+//
+// socket-related test cases
+//
+// Authors:
+//  Steffen Kiess (s-kiess@web.de)
+//
+// Copyright (C) 2015 Steffen Kiess
+//
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.InteropServices;
+
+using Mono.Unix;
+using Mono.Unix.Native;
+
+using NUnit.Framework;
+
+namespace MonoTests.Mono.Unix.Native
+{
+       [TestFixture, Category ("NotDotNet")]
+       public class SocketTest {
+
+               string TempFolder;
+
+               [SetUp]
+               public void SetUp ()
+               {
+                       TempFolder = Path.Combine (Path.GetTempPath (), this.GetType ().FullName);
+
+                       if (Directory.Exists (TempFolder))
+                               Directory.Delete (TempFolder, true);
+
+                       Directory.CreateDirectory (TempFolder);
+               }
+
+               [TearDown]
+               public void TearDown()
+               {
+                       if (Directory.Exists (TempFolder))
+                               Directory.Delete (TempFolder, true);
+               }
+
+               // Set a timeout on all sockets to make sure that if a test fails it
+               // won't cause the program to hang
+               void SetTimeout (int socket)
+               {
+                       var timeout = new Timeval {
+                               tv_sec = 0,
+                               tv_usec = 500000,
+                       };
+                       if (Syscall.setsockopt (socket, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_RCVTIMEO, timeout) < 0 ||
+                                       Syscall.setsockopt (socket, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_SNDTIMEO, timeout) < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+               }
+
+               void WithSocketPair (Action<int, int> f)
+               {
+                       int socket1, socket2;
+                       if (Syscall.socketpair (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, out socket1, out socket2) < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+                       try {
+                               SetTimeout (socket1);
+                               SetTimeout (socket2);
+
+                               f (socket1, socket2);
+                       } finally {
+                               int r0 = Syscall.close (socket1);
+                               int r1 = Syscall.close (socket2);
+                               if (r0 < 0 || r1 < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+                       }
+               }
+
+               void WithSockets (UnixAddressFamily af, UnixSocketType type, UnixSocketProtocol protocol, Action<int, int> f)
+               {
+                       int so1, so2;
+                       if ((so1 = Syscall.socket (af, type, protocol)) < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+                       try {
+                               if ((so2 = Syscall.socket (af, type, protocol)) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+                               try {
+                                       SetTimeout (so1);
+                                       SetTimeout (so2);
+
+                                       f (so1, so2);
+                               } finally {
+                                       if (Syscall.close (so2) < 0)
+                                               UnixMarshal.ThrowExceptionForLastError ();
+                               }
+                       } finally {
+                               if (Syscall.close (so1) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+                       }
+               }
+
+               [Test]
+               public void Socket ()
+               {
+                       int socket;
+                       if ((socket = Syscall.socket (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0)) < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+
+                       if (Syscall.close (socket) < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+               }
+
+               [Test]
+               public void SocketPair ()
+               {
+                       int socket1, socket2;
+                       if (Syscall.socketpair (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, out socket1, out socket2) < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+
+                       int r0 = Syscall.close (socket1);
+                       int r1 = Syscall.close (socket2);
+                       if (r0 < 0 || r1 < 0)
+                               UnixMarshal.ThrowExceptionForLastError ();
+               }
+
+               [Test]
+               public void SendRecv ()
+               {
+                       WithSocketPair ((so1, so2) => {
+                               long ret;
+                               var buffer1 = new byte[] { 42, 43, 44 };
+                               ret = Syscall.send (so1, buffer1, (ulong) buffer1.Length, 0);
+                               if (ret < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               var buffer2 = new byte[1024];
+                               ret = Syscall.recv (so2, buffer2, (ulong) buffer2.Length, 0);
+                               if (ret < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               Assert.AreEqual (buffer1.Length, ret);
+                               for (int i = 0; i < buffer1.Length; i++)
+                                       Assert.AreEqual (buffer1[i], buffer2[i]);
+                       });
+               }
+
+               [Test]
+               public void SockOpt ()
+               {
+                       WithSockets (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
+                               // Set SO_REUSEADDR to 1
+                               if (Syscall.setsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, 1) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               // Get and check SO_REUSEADDR
+                               int value;
+                               if (Syscall.getsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, out value) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+                               Assert.AreEqual (value, 1);
+
+                               // Set SO_REUSEADDR to 0
+                               if (Syscall.setsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, new byte[10], 4) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               // Get and check SO_REUSEADDR
+                               var buffer = new byte[15];
+                               long size = 12;
+                               if (Syscall.getsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, buffer, ref size) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+                               Assert.AreEqual (size, 4);
+                               for (int i = 0; i < size; i++)
+                                       Assert.AreEqual (buffer[i], 0);
+                       });
+               }
+
+               [Test]
+               public void SockOptLinger ()
+               {
+                       WithSockets (UnixAddressFamily.AF_INET, UnixSocketType.SOCK_STREAM, UnixSocketProtocol.IPPROTO_TCP, (so1, so2) => {
+                               Linger linger = new Linger {
+                                       l_onoff = 1,
+                                       l_linger = 42,
+                               };
+                               // Set SO_LINGER
+                               if (Syscall.setsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_LINGER, linger) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               // Get and check SO_LINGER
+                               Linger value;
+                               if (Syscall.getsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_LINGER, out value) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+                               Assert.AreEqual (linger, value);
+                       });
+               }
+
+               [Test]
+               public void Shutdown ()
+               {
+                       WithSocketPair ((so1, so2) => {
+                               if (Syscall.shutdown (so1, ShutdownOption.SHUT_WR) < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               var buffer2 = new byte[1024];
+                               long ret = Syscall.recv (so2, buffer2, (ulong) buffer2.Length, 0);
+                               if (ret < 0)
+                                       UnixMarshal.ThrowExceptionForLastError ();
+
+                               Assert.AreEqual (ret, 0);
+                       });
+               }
+       }
+}
+
+// vim: noexpandtab
+// Local Variables: 
+// tab-width: 4
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// End: 
index b7b4e6fc695e9539dc22237d55b0b1a45c766ff2..8d4c63c6564678dbb0754d4a4be4e381eca79321 100644 (file)
@@ -15,6 +15,7 @@ using System;
 using System.Text;
 using System.Threading;
 using Mono.Unix;
+using Mono.Unix.Android;
 using Mono.Unix.Native;
 #if !MONODROID
 namespace NUnit.Framework.SyntaxHelpers { class Dummy {} }
@@ -117,6 +118,7 @@ namespace MonoTests.Mono.Unix {
                }
 
                [Test]
+               [Category ("AndroidNotWorking")] // Crashes (silently) the runtime in similar fashion to real-time signals
                public void TestSignumProperty ()
                {
                        UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
@@ -127,6 +129,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestRealTimeCstor ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts = new RealTimeSignum (0);
                        using (UnixSignal s = new UnixSignal (rts))
                        {
@@ -140,6 +144,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestSignumPropertyThrows ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        UnixSignal signal1 = new UnixSignal (new RealTimeSignum (0));
                        Signum s = signal1.Signum;
                }
@@ -148,6 +154,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestRealTimeSignumProperty ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts = new RealTimeSignum (0);
                        UnixSignal signal1 = new UnixSignal (rts);
                        Assert.That (signal1.RealTimeSignum, Is.EqualTo (rts));
@@ -158,6 +166,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestRealTimePropertyThrows ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
                        RealTimeSignum s = signal1.RealTimeSignum;
                }
@@ -166,6 +176,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestRaiseRTMINSignal ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        RealTimeSignum rts = new RealTimeSignum (0);
                        using (UnixSignal signal = new UnixSignal (rts))
                        {
@@ -180,6 +192,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestRaiseRTMINPlusOneSignal ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        /*this number is a guestimate, but it's ok*/
                        for (int i = 1; i < 10; ++i) {
                                RealTimeSignum rts = new RealTimeSignum (i);
@@ -205,6 +219,8 @@ namespace MonoTests.Mono.Unix {
                [Category ("NotOnMac")]
                public void TestCanRegisterRTSignalMultipleTimes ()
                {
+                       if (!TestHelper.CanUseRealTimeSignals ())
+                               return;
                        /*this number is a guestimate, but it's ok*/
                        for (int i = 1; i < 10; ++i) {
                                RealTimeSignum rts = new RealTimeSignum (i);
index 89d524cd1b9d50876d7b45209a97d904371e5bb3..e5681ff8ff5bf166c97dd42c23e421b8963c6445 100644 (file)
@@ -1 +1 @@
-#include net_4_5_System.Core.dll.sources
+#include net_4_x_System.Core.dll.sources
index 597245c0e81ec04b7fae28f07db60c8d491e8c7b..652c5631202c4c0583ffed3754dae61ac4e60c1d 100644 (file)
@@ -1 +1 @@
-#include net_4_5_System.Data.dll.sources
+#include net_4_x_System.Data.dll.sources
index abb05921042ee5a72d4f5c36457a64208cde3aa2..05b5fe62681f3f981b067777d1cb7a7f9f32a03b 100644 (file)
@@ -363,6 +363,10 @@ namespace System.Net.Http.Headers
                                first = false;
                        }
 
+                       // Return null for empty values list
+                       if (first)
+                               return null;
+
                        return sb.ToString ();
                }
 
index ccf9a808c25b9e005b32d1d846c0efa98ef9f8ca..087e62474d2f986c1b84228fb3a2e30201e4d952 100644 (file)
@@ -30,6 +30,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Collections.Specialized;
 using System.Net.Http.Headers;
+using System.Linq;
 
 namespace System.Net.Http
 {
@@ -274,7 +275,18 @@ namespace System.Net.Http
                        // Add request headers
                        var headers = wr.Headers;
                        foreach (var header in request.Headers) {
-                               headers.AddValue (header.Key, HttpRequestHeaders.GetSingleHeaderString (header.Key, header.Value));
+                               var values = header.Value;
+                               if (header.Key == "Transfer-Encoding") {
+                                       // Chunked Transfer-Encoding is never set for HttpWebRequest. It's detected
+                                       // from ContentLength by HttpWebRequest
+                                       values = values.Where (l => l != "chunked");
+                               }
+
+                               var values_formated = HttpRequestHeaders.GetSingleHeaderString (header.Key, values);
+                               if (values_formated == null)
+                                       continue;
+
+                               headers.AddValue (header.Key, values_formated);
                        }
                        
                        return wr;
index a6c69de2bb99e96640a181ab26b8ddef1712a130..ec049a932105ea973be9d262937694c89f83348e 100644 (file)
@@ -606,6 +606,62 @@ namespace MonoTests.System.Net.Http
                        }
                }
 
+               [Test]
+               public void Send_Transfer_Encoding_Chunked ()
+               {
+                       bool? failed = null;
+
+                       var listener = CreateListener (l => {
+                               var request = l.Request;
+
+                               try {
+                                       Assert.AreEqual (1, request.Headers.Count, "#1");
+                                       failed = false;
+                               } catch {
+                                       failed = true;
+                               }
+                       });
+
+                       try {
+                               var client = new HttpClient ();
+                               client.DefaultRequestHeaders.TransferEncodingChunked = true;
+
+                               client.GetAsync (LocalServer).Wait ();
+
+                               Assert.AreEqual (false, failed, "#102");
+                       } finally {
+                               listener.Abort ();
+                               listener.Close ();
+                       }
+               }
+
+               [Test]
+               public void Send_Transfer_Encoding_Custom ()
+               {
+                       bool? failed = null;
+
+                       var listener = CreateListener (l => {
+                               failed = true;
+                       });
+
+                       try {
+                               var client = new HttpClient ();
+                               client.DefaultRequestHeaders.TransferEncoding.Add (new TransferCodingHeaderValue ("chunked2"));
+
+                               var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+
+                               try {
+                                       client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Wait ();
+                                       Assert.Fail ("#1");
+                               } catch (AggregateException e) {
+                                       Assert.AreEqual (typeof (ProtocolViolationException), e.InnerException.GetType (), "#2");
+                               }
+                               Assert.IsNull (failed, "#102");
+                       } finally {
+                               listener.Abort ();
+                               listener.Close ();
+                       }
+               }
 
                [Test]
                public void Send_Complete_Content ()
diff --git a/mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources
deleted file mode 100644 (file)
index b40b2a1..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-../../build/common/Consts.cs
-Assembly/AssemblyInfo.cs
-System.Net.Http/ByteArrayContent.cs
-System.Net.Http/ClientCertificateOption.cs
-System.Net.Http/DelegatingHandler.cs
-System.Net.Http/FormUrlEncodedContent.cs
-System.Net.Http/HttpClient.cs
-System.Net.Http/HttpClientHandler.cs
-System.Net.Http/HttpCompletionOption.cs
-System.Net.Http/HttpContent.cs
-System.Net.Http/HttpMessageHandler.cs
-System.Net.Http/HttpMessageInvoker.cs
-System.Net.Http/HttpMethod.cs
-System.Net.Http/HttpRequestException.cs
-System.Net.Http/HttpRequestMessage.cs
-System.Net.Http/HttpResponseMessage.cs
-System.Net.Http/MessageProcessingHandler.cs
-System.Net.Http/MultipartContent.cs
-System.Net.Http/MultipartFormDataContent.cs
-System.Net.Http/StreamContent.cs
-System.Net.Http/StringContent.cs
-System.Net.Http.Headers/AuthenticationHeaderValue.cs
-System.Net.Http.Headers/CacheControlHeaderValue.cs
-System.Net.Http.Headers/CollectionExtensions.cs
-System.Net.Http.Headers/CollectionParser.cs
-System.Net.Http.Headers/ContentDispositionHeaderValue.cs
-System.Net.Http.Headers/ContentRangeHeaderValue.cs
-System.Net.Http.Headers/EntityTagHeaderValue.cs
-System.Net.Http.Headers/HashCodeCalculator.cs
-System.Net.Http.Headers/HeaderInfo.cs
-System.Net.Http.Headers/HttpContentHeaders.cs
-System.Net.Http.Headers/HttpHeaderKind.cs
-System.Net.Http.Headers/HttpHeaders.cs
-System.Net.Http.Headers/HttpHeaderValueCollection.cs
-System.Net.Http.Headers/HttpRequestHeaders.cs
-System.Net.Http.Headers/HttpResponseHeaders.cs
-System.Net.Http.Headers/Lexer.cs
-System.Net.Http.Headers/MediaTypeHeaderValue.cs
-System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs
-System.Net.Http.Headers/NameValueHeaderValue.cs
-System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs
-System.Net.Http.Headers/Parser.cs
-System.Net.Http.Headers/ProductHeaderValue.cs
-System.Net.Http.Headers/ProductInfoHeaderValue.cs
-System.Net.Http.Headers/QualityValue.cs
-System.Net.Http.Headers/RangeConditionHeaderValue.cs
-System.Net.Http.Headers/RangeHeaderValue.cs
-System.Net.Http.Headers/RangeItemHeaderValue.cs
-System.Net.Http.Headers/RetryConditionHeaderValue.cs
-System.Net.Http.Headers/StringWithQualityHeaderValue.cs
-System.Net.Http.Headers/TransferCodingHeaderValue.cs
-System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs
-System.Net.Http.Headers/ViaHeaderValue.cs
-System.Net.Http.Headers/WarningHeaderValue.cs
\ No newline at end of file
diff --git a/mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources
deleted file mode 100644 (file)
index 685ab03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include monotouch_System.Net.Http.dll.sources
\ No newline at end of file
index e15a51bfe02a2bc522134f66a43ee6786b8881b5..a34e32c78a41be95ad6f4bab3773c9296c0b10f9 100644 (file)
@@ -94,7 +94,7 @@ namespace MonoTests.Remoting {
                };
                
                [Test] // HttpChannel.Parse ()
-               [Ignore ("Fails on MS")]
+               [Category ("NotWorking")] // Fails on MS
                public void ParseURL ()
                {
                        HttpChannel channel;
index 17c4f437aab4073bd9b97ac7197b17746eaa7c4a..5feabf388ccf8582d9abe59f5918ed1358682ae3 100644 (file)
@@ -1 +1 @@
-#include net_4_5_System.Runtime.Serialization.dll.sources
+#include net_4_x_System.Runtime.Serialization.dll.sources
index ca5e2e34c81bbd40723ec97a1865f59a52b58207..c005094275c5a9c5020dc612fd811eeb8fa8af98 100644 (file)
@@ -584,10 +584,14 @@ namespace System.ServiceModel.Dispatcher
                        {
                                Message msg;
                                var input = (IInputChannel) result.AsyncState;
-                               if (input.EndTryReceive (result, out msg))
-                                       ProcessInput (input, msg);
-                               else
+                               try {
+                                       if (input.EndTryReceive (result, out msg))
+                                               ProcessInput (input, msg);
+                                       else
+                                               input.Close ();
+                               } catch (ObjectDisposedException) {
                                        input.Close ();
+                               }
                        }
 
                        void ProcessRequest (IReplyChannel reply, RequestContext rc)
index 354d4c8b410809c434d8f2f7966383578f56c29d..36ea57b5b9fd7b6170cc447d46b2da4cc1f19b26 100644 (file)
@@ -461,8 +461,6 @@ namespace System.ServiceModel.MonoInternal
                        if (p == parameters)
                                return retval;
 
-                       if (p.Length != parameters.Length)
-                               throw new InvalidOperationException ();
                        Array.Copy (p, parameters, p.Length);
                        return retval;
                }
index deb325709e5eb9cb1235044bf952f85994b148c6..0cde2c9bdec8b0b276078978bc3ed79db1fe8434 100644 (file)
@@ -128,6 +128,7 @@ System.ServiceModel.Description/WsdlImporterTest.cs
 System.ServiceModel.Dispatcher/ActionFilterTest.cs
 System.ServiceModel.Dispatcher/Bug652331Test.cs
 System.ServiceModel.Dispatcher/Bug652331_2Test.cs
+System.ServiceModel.Dispatcher/Bug32886Test.cs
 System.ServiceModel.Dispatcher/ChannelDispatcherTest.cs
 System.ServiceModel.Dispatcher/DispatchOperationTest.cs
 System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs
diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug32886Test.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug32886Test.cs
new file mode 100644 (file)
index 0000000..1562ba1
--- /dev/null
@@ -0,0 +1,706 @@
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using System.Threading;
+using NUnit.Framework;
+
+using WebServiceMoonlightTest.ServiceReference1;
+
+using MonoTests.Helpers;
+
+namespace MonoTests.System.ServiceModel.Dispatcher
+{
+       [TestFixture]
+       public class Bug32886
+       {
+               [Test]
+               public void Bug32886_Test () // test in one of the comment
+               {
+                       // Init service
+                       int port = NetworkHelpers.FindFreePort ();
+                       ServiceHost serviceHost = new ServiceHost (typeof (TempConvertSoapImpl), new Uri ("http://localhost:" + port + "/TempConvertSoap"));
+                       serviceHost.AddServiceEndpoint (typeof (TempConvertSoap), new BasicHttpBinding (), string.Empty);
+
+                       // Enable metadata exchange (WSDL publishing)
+                       var mexBehavior = new ServiceMetadataBehavior ();
+                       mexBehavior.HttpGetEnabled = true;
+                       serviceHost.Description.Behaviors.Add (mexBehavior);
+                       serviceHost.AddServiceEndpoint (typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding (), "mex");
+
+                       serviceHost.Open ();
+
+                       try {
+                               // client
+                               var binding = new BasicHttpBinding ();
+                               var remoteAddress = new EndpointAddress ("http://localhost:" + port + "/TempConvertSoap");
+                               var client = new TempConvertSoapClient (binding, remoteAddress);
+
+                               var wait = new ManualResetEvent (false);
+                               client.CelsiusToFahrenheitCompleted += delegate (object o, CelsiusToFahrenheitCompletedEventArgs e) {
+                                       if (e.Error != null)
+                                               throw e.Error;
+                                       Assert.AreEqual ("76.1", e.Result, "#1");
+                                       wait.Set ();
+                               };
+
+                               client.CelsiusToFahrenheitAsync ("24.5");
+                               if (!wait.WaitOne (TimeSpan.FromSeconds (20)))
+                                       Assert.Fail ("timeout");
+                       } finally {
+                               serviceHost.Close ();
+                       }
+               }
+
+               class TempConvertSoapImpl : TempConvertSoap
+               {
+                       public FahrenheitToCelsiusResponse FarenheitToCelsius (FahrenheitToCelsiusRequest request)
+                       {
+                               var farenheit = double.Parse (request.Body.Fahrenheit);
+                               var celsius = ((farenheit - 32) / 9) * 5;
+                               return new FahrenheitToCelsiusResponse (new FahrenheitToCelsiusResponseBody (celsius.ToString ()));
+                       }
+
+                       public CelsiusToFahrenheitResponse CelsiusToFarenheit (CelsiusToFahrenheitRequest request)
+                       {
+                               var celsius = double.Parse (request.Body.Celsius);
+                               var farenheit = ((celsius * 9) / 5) + 32;
+                               return new CelsiusToFahrenheitResponse (new CelsiusToFahrenheitResponseBody (farenheit.ToString ()));
+                       }
+
+                       Func<FahrenheitToCelsiusRequest,FahrenheitToCelsiusResponse> farenheitToCelsius;
+                       Func<CelsiusToFahrenheitRequest,CelsiusToFahrenheitResponse> celsiusToFarenheit;
+
+                       public IAsyncResult BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, AsyncCallback callback, object asyncState)
+                       {
+                               if (farenheitToCelsius == null)
+                                       farenheitToCelsius = new Func<FahrenheitToCelsiusRequest,FahrenheitToCelsiusResponse> (FarenheitToCelsius);
+                               return farenheitToCelsius.BeginInvoke (request, callback, asyncState);
+                       }
+
+                       public FahrenheitToCelsiusResponse EndFahrenheitToCelsius (IAsyncResult result)
+                       {
+                               return farenheitToCelsius.EndInvoke (result);
+                       }
+
+                       public IAsyncResult BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, AsyncCallback callback, object asyncState)
+                       {
+                               if (celsiusToFarenheit == null)
+                                       celsiusToFarenheit = new Func<CelsiusToFahrenheitRequest,CelsiusToFahrenheitResponse> (CelsiusToFarenheit);
+                               return celsiusToFarenheit.BeginInvoke (request, callback, asyncState);
+                       }
+
+                       public CelsiusToFahrenheitResponse EndCelsiusToFahrenheit (IAsyncResult result)
+                       {
+                               return celsiusToFarenheit.EndInvoke (result);
+                       }
+               }
+       }
+}
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.34003
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+// 
+// This code was auto-generated by SlSvcUtil, version 5.0.61118.0
+// 
+
+
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ServiceModel.ServiceContractAttribute (Namespace = "http://www.w3schools.com/webservices/", ConfigurationName = "TempConvertSoap")]
+public interface TempConvertSoap
+{
+
+       [System.ServiceModel.OperationContractAttribute (AsyncPattern = true, Action = "http://www.w3schools.com/webservices/FahrenheitToCelsius", ReplyAction = "*")]
+       System.IAsyncResult BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, System.AsyncCallback callback, object asyncState);
+
+       FahrenheitToCelsiusResponse EndFahrenheitToCelsius (System.IAsyncResult result);
+
+       [System.ServiceModel.OperationContractAttribute (AsyncPattern = true, Action = "http://www.w3schools.com/webservices/CelsiusToFahrenheit", ReplyAction = "*")]
+       System.IAsyncResult BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, System.AsyncCallback callback, object asyncState);
+
+       CelsiusToFahrenheitResponse EndCelsiusToFahrenheit (System.IAsyncResult result);
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class FahrenheitToCelsiusRequest
+{
+
+       [System.ServiceModel.MessageBodyMemberAttribute (Name = "FahrenheitToCelsius", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+       public FahrenheitToCelsiusRequestBody Body;
+
+       public FahrenheitToCelsiusRequest ()
+       {
+       }
+
+       public FahrenheitToCelsiusRequest (FahrenheitToCelsiusRequestBody Body)
+       {
+               this.Body = Body;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class FahrenheitToCelsiusRequestBody
+{
+
+       [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+       public string Fahrenheit;
+
+       public FahrenheitToCelsiusRequestBody ()
+       {
+       }
+
+       public FahrenheitToCelsiusRequestBody (string Fahrenheit)
+       {
+               this.Fahrenheit = Fahrenheit;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class FahrenheitToCelsiusResponse
+{
+
+       [System.ServiceModel.MessageBodyMemberAttribute (Name = "FahrenheitToCelsiusResponse", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+       public FahrenheitToCelsiusResponseBody Body;
+
+       public FahrenheitToCelsiusResponse ()
+       {
+       }
+
+       public FahrenheitToCelsiusResponse (FahrenheitToCelsiusResponseBody Body)
+       {
+               this.Body = Body;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class FahrenheitToCelsiusResponseBody
+{
+
+       [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+       public string FahrenheitToCelsiusResult;
+
+       public FahrenheitToCelsiusResponseBody ()
+       {
+       }
+
+       public FahrenheitToCelsiusResponseBody (string FahrenheitToCelsiusResult)
+       {
+               this.FahrenheitToCelsiusResult = FahrenheitToCelsiusResult;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class CelsiusToFahrenheitRequest
+{
+
+       [System.ServiceModel.MessageBodyMemberAttribute (Name = "CelsiusToFahrenheit", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+       public CelsiusToFahrenheitRequestBody Body;
+
+       public CelsiusToFahrenheitRequest ()
+       {
+       }
+
+       public CelsiusToFahrenheitRequest (CelsiusToFahrenheitRequestBody Body)
+       {
+               this.Body = Body;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class CelsiusToFahrenheitRequestBody
+{
+
+       [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+       public string Celsius;
+
+       public CelsiusToFahrenheitRequestBody ()
+       {
+       }
+
+       public CelsiusToFahrenheitRequestBody (string Celsius)
+       {
+               this.Celsius = Celsius;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class CelsiusToFahrenheitResponse
+{
+
+       [System.ServiceModel.MessageBodyMemberAttribute (Name = "CelsiusToFahrenheitResponse", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+       public CelsiusToFahrenheitResponseBody Body;
+
+       public CelsiusToFahrenheitResponse ()
+       {
+       }
+
+       public CelsiusToFahrenheitResponse (CelsiusToFahrenheitResponseBody Body)
+       {
+               this.Body = Body;
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class CelsiusToFahrenheitResponseBody
+{
+
+       [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+       public string CelsiusToFahrenheitResult;
+
+       public CelsiusToFahrenheitResponseBody ()
+       {
+       }
+
+       public CelsiusToFahrenheitResponseBody (string CelsiusToFahrenheitResult)
+       {
+               this.CelsiusToFahrenheitResult = CelsiusToFahrenheitResult;
+       }
+}
+
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public interface TempConvertSoapChannel : TempConvertSoap, System.ServiceModel.IClientChannel
+{
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public partial class FahrenheitToCelsiusCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
+{
+
+       private object[] results;
+
+       public FahrenheitToCelsiusCompletedEventArgs (object[] results, System.Exception exception, bool cancelled, object userState) :
+       base (exception, cancelled, userState)
+       {
+               this.results = results;
+       }
+
+       public string Result {
+               get {
+                       base.RaiseExceptionIfNecessary ();
+                       return ((string)(this.results [0]));
+               }
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public partial class CelsiusToFahrenheitCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
+{
+
+       private object[] results;
+
+       public CelsiusToFahrenheitCompletedEventArgs (object[] results, System.Exception exception, bool cancelled, object userState) :
+       base (exception, cancelled, userState)
+       {
+               this.results = results;
+       }
+
+       public string Result {
+               get {
+                       base.RaiseExceptionIfNecessary ();
+                       return ((string)(this.results [0]));
+               }
+       }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public partial class TempConvertSoapClient : System.ServiceModel.ClientBase<TempConvertSoap>, TempConvertSoap
+{
+
+       private BeginOperationDelegate onBeginFahrenheitToCelsiusDelegate;
+
+       private EndOperationDelegate onEndFahrenheitToCelsiusDelegate;
+
+       private System.Threading.SendOrPostCallback onFahrenheitToCelsiusCompletedDelegate;
+
+       private BeginOperationDelegate onBeginCelsiusToFahrenheitDelegate;
+
+       private EndOperationDelegate onEndCelsiusToFahrenheitDelegate;
+
+       private System.Threading.SendOrPostCallback onCelsiusToFahrenheitCompletedDelegate;
+
+       private BeginOperationDelegate onBeginOpenDelegate;
+
+       private EndOperationDelegate onEndOpenDelegate;
+
+       private System.Threading.SendOrPostCallback onOpenCompletedDelegate;
+
+       private BeginOperationDelegate onBeginCloseDelegate;
+
+       private EndOperationDelegate onEndCloseDelegate;
+
+       private System.Threading.SendOrPostCallback onCloseCompletedDelegate;
+
+       public TempConvertSoapClient ()
+       {
+       }
+
+       public TempConvertSoapClient (string endpointConfigurationName) :
+       base (endpointConfigurationName)
+       {
+       }
+
+       public TempConvertSoapClient (string endpointConfigurationName, string remoteAddress) :
+       base (endpointConfigurationName, remoteAddress)
+       {
+       }
+
+       public TempConvertSoapClient (string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
+       base (endpointConfigurationName, remoteAddress)
+       {
+       }
+
+       public TempConvertSoapClient (System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
+       base (binding, remoteAddress)
+       {
+       }
+
+       public System.Net.CookieContainer CookieContainer {
+               get {
+                       System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager> ();
+                       if ((httpCookieContainerManager != null)) {
+                               return httpCookieContainerManager.CookieContainer;
+                       } else {
+                               return null;
+                       }
+               }
+               set {
+                       System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager> ();
+                       if ((httpCookieContainerManager != null)) {
+                               httpCookieContainerManager.CookieContainer = value;
+                       } else {
+                               throw new System.InvalidOperationException ("Unable to set the CookieContainer. Please make sure the binding contains an HttpC" +
+                                       "ookieContainerBindingElement.");
+                       }
+               }
+       }
+
+       public event System.EventHandler<FahrenheitToCelsiusCompletedEventArgs> FahrenheitToCelsiusCompleted;
+
+       public event System.EventHandler<CelsiusToFahrenheitCompletedEventArgs> CelsiusToFahrenheitCompleted;
+
+       public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> OpenCompleted;
+
+       public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> CloseCompleted;
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       System.IAsyncResult TempConvertSoap.BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, System.AsyncCallback callback, object asyncState)
+       {
+               return base.Channel.BeginFahrenheitToCelsius (request, callback, asyncState);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       private System.IAsyncResult BeginFahrenheitToCelsius (string Fahrenheit, System.AsyncCallback callback, object asyncState)
+       {
+               FahrenheitToCelsiusRequest inValue = new FahrenheitToCelsiusRequest ();
+               inValue.Body = new FahrenheitToCelsiusRequestBody ();
+               inValue.Body.Fahrenheit = Fahrenheit;
+               return ((TempConvertSoap)(this)).BeginFahrenheitToCelsius (inValue, callback, asyncState);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       FahrenheitToCelsiusResponse TempConvertSoap.EndFahrenheitToCelsius (System.IAsyncResult result)
+       {
+               return base.Channel.EndFahrenheitToCelsius (result);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       private string EndFahrenheitToCelsius (System.IAsyncResult result)
+       {
+               FahrenheitToCelsiusResponse retVal = ((TempConvertSoap)(this)).EndFahrenheitToCelsius (result);
+               return retVal.Body.FahrenheitToCelsiusResult;
+       }
+
+       private System.IAsyncResult OnBeginFahrenheitToCelsius (object[] inValues, System.AsyncCallback callback, object asyncState)
+       {
+               string Fahrenheit = ((string)(inValues [0]));
+               return this.BeginFahrenheitToCelsius (Fahrenheit, callback, asyncState);
+       }
+
+       private object[] OnEndFahrenheitToCelsius (System.IAsyncResult result)
+       {
+               string retVal = this.EndFahrenheitToCelsius (result);
+               return new object[] {
+                       retVal
+               };
+       }
+
+       private void OnFahrenheitToCelsiusCompleted (object state)
+       {
+               if ((this.FahrenheitToCelsiusCompleted != null)) {
+                       InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                       this.FahrenheitToCelsiusCompleted (this, new FahrenheitToCelsiusCompletedEventArgs (e.Results, e.Error, e.Cancelled, e.UserState));
+               }
+       }
+
+       public void FahrenheitToCelsiusAsync (string Fahrenheit)
+       {
+               this.FahrenheitToCelsiusAsync (Fahrenheit, null);
+       }
+
+       public void FahrenheitToCelsiusAsync (string Fahrenheit, object userState)
+       {
+               if ((this.onBeginFahrenheitToCelsiusDelegate == null)) {
+                       this.onBeginFahrenheitToCelsiusDelegate = new BeginOperationDelegate (this.OnBeginFahrenheitToCelsius);
+               }
+               if ((this.onEndFahrenheitToCelsiusDelegate == null)) {
+                       this.onEndFahrenheitToCelsiusDelegate = new EndOperationDelegate (this.OnEndFahrenheitToCelsius);
+               }
+               if ((this.onFahrenheitToCelsiusCompletedDelegate == null)) {
+                       this.onFahrenheitToCelsiusCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnFahrenheitToCelsiusCompleted);
+               }
+               base.InvokeAsync (this.onBeginFahrenheitToCelsiusDelegate, new object[] {
+                       Fahrenheit
+               }, this.onEndFahrenheitToCelsiusDelegate, this.onFahrenheitToCelsiusCompletedDelegate, userState);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       System.IAsyncResult TempConvertSoap.BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, System.AsyncCallback callback, object asyncState)
+       {
+               return base.Channel.BeginCelsiusToFahrenheit (request, callback, asyncState);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       private System.IAsyncResult BeginCelsiusToFahrenheit (string Celsius, System.AsyncCallback callback, object asyncState)
+       {
+               CelsiusToFahrenheitRequest inValue = new CelsiusToFahrenheitRequest ();
+               inValue.Body = new CelsiusToFahrenheitRequestBody ();
+               inValue.Body.Celsius = Celsius;
+               return ((TempConvertSoap)(this)).BeginCelsiusToFahrenheit (inValue, callback, asyncState);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       CelsiusToFahrenheitResponse TempConvertSoap.EndCelsiusToFahrenheit (System.IAsyncResult result)
+       {
+               return base.Channel.EndCelsiusToFahrenheit (result);
+       }
+
+       [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+       private string EndCelsiusToFahrenheit (System.IAsyncResult result)
+       {
+               CelsiusToFahrenheitResponse retVal = ((TempConvertSoap)(this)).EndCelsiusToFahrenheit (result);
+               return retVal.Body.CelsiusToFahrenheitResult;
+       }
+
+       private System.IAsyncResult OnBeginCelsiusToFahrenheit (object[] inValues, System.AsyncCallback callback, object asyncState)
+       {
+               string Celsius = ((string)(inValues [0]));
+               return this.BeginCelsiusToFahrenheit (Celsius, callback, asyncState);
+       }
+
+       private object[] OnEndCelsiusToFahrenheit (System.IAsyncResult result)
+       {
+               string retVal = this.EndCelsiusToFahrenheit (result);
+               return new object[] {
+                       retVal
+               };
+       }
+
+       private void OnCelsiusToFahrenheitCompleted (object state)
+       {
+               if ((this.CelsiusToFahrenheitCompleted != null)) {
+                       InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                       this.CelsiusToFahrenheitCompleted (this, new CelsiusToFahrenheitCompletedEventArgs (e.Results, e.Error, e.Cancelled, e.UserState));
+               }
+       }
+
+       public void CelsiusToFahrenheitAsync (string Celsius)
+       {
+               this.CelsiusToFahrenheitAsync (Celsius, null);
+       }
+
+       public void CelsiusToFahrenheitAsync (string Celsius, object userState)
+       {
+               if ((this.onBeginCelsiusToFahrenheitDelegate == null)) {
+                       this.onBeginCelsiusToFahrenheitDelegate = new BeginOperationDelegate (this.OnBeginCelsiusToFahrenheit);
+               }
+               if ((this.onEndCelsiusToFahrenheitDelegate == null)) {
+                       this.onEndCelsiusToFahrenheitDelegate = new EndOperationDelegate (this.OnEndCelsiusToFahrenheit);
+               }
+               if ((this.onCelsiusToFahrenheitCompletedDelegate == null)) {
+                       this.onCelsiusToFahrenheitCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnCelsiusToFahrenheitCompleted);
+               }
+               base.InvokeAsync (this.onBeginCelsiusToFahrenheitDelegate, new object[] {
+                       Celsius
+               }, this.onEndCelsiusToFahrenheitDelegate, this.onCelsiusToFahrenheitCompletedDelegate, userState);
+       }
+
+       private System.IAsyncResult OnBeginOpen (object[] inValues, System.AsyncCallback callback, object asyncState)
+       {
+               return ((System.ServiceModel.ICommunicationObject)(this)).BeginOpen (callback, asyncState);
+       }
+
+       private object[] OnEndOpen (System.IAsyncResult result)
+       {
+               ((System.ServiceModel.ICommunicationObject)(this)).EndOpen (result);
+               return null;
+       }
+
+       private void OnOpenCompleted (object state)
+       {
+               if ((this.OpenCompleted != null)) {
+                       InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                       this.OpenCompleted (this, new System.ComponentModel.AsyncCompletedEventArgs (e.Error, e.Cancelled, e.UserState));
+               }
+       }
+
+       public void OpenAsync ()
+       {
+               this.OpenAsync (null);
+       }
+
+       public void OpenAsync (object userState)
+       {
+               if ((this.onBeginOpenDelegate == null)) {
+                       this.onBeginOpenDelegate = new BeginOperationDelegate (this.OnBeginOpen);
+               }
+               if ((this.onEndOpenDelegate == null)) {
+                       this.onEndOpenDelegate = new EndOperationDelegate (this.OnEndOpen);
+               }
+               if ((this.onOpenCompletedDelegate == null)) {
+                       this.onOpenCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnOpenCompleted);
+               }
+               base.InvokeAsync (this.onBeginOpenDelegate, null, this.onEndOpenDelegate, this.onOpenCompletedDelegate, userState);
+       }
+
+       private System.IAsyncResult OnBeginClose (object[] inValues, System.AsyncCallback callback, object asyncState)
+       {
+               return ((System.ServiceModel.ICommunicationObject)(this)).BeginClose (callback, asyncState);
+       }
+
+       private object[] OnEndClose (System.IAsyncResult result)
+       {
+               ((System.ServiceModel.ICommunicationObject)(this)).EndClose (result);
+               return null;
+       }
+
+       private void OnCloseCompleted (object state)
+       {
+               if ((this.CloseCompleted != null)) {
+                       InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                       this.CloseCompleted (this, new System.ComponentModel.AsyncCompletedEventArgs (e.Error, e.Cancelled, e.UserState));
+               }
+       }
+
+       public void CloseAsync ()
+       {
+               this.CloseAsync (null);
+       }
+
+       public void CloseAsync (object userState)
+       {
+               if ((this.onBeginCloseDelegate == null)) {
+                       this.onBeginCloseDelegate = new BeginOperationDelegate (this.OnBeginClose);
+               }
+               if ((this.onEndCloseDelegate == null)) {
+                       this.onEndCloseDelegate = new EndOperationDelegate (this.OnEndClose);
+               }
+               if ((this.onCloseCompletedDelegate == null)) {
+                       this.onCloseCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnCloseCompleted);
+               }
+               base.InvokeAsync (this.onBeginCloseDelegate, null, this.onEndCloseDelegate, this.onCloseCompletedDelegate, userState);
+       }
+
+       protected override TempConvertSoap CreateChannel ()
+       {
+               return new TempConvertSoapClientChannel (this);
+       }
+
+       private class TempConvertSoapClientChannel : ChannelBase<TempConvertSoap>, TempConvertSoap
+       {
+
+               public TempConvertSoapClientChannel (System.ServiceModel.ClientBase<TempConvertSoap> client) :
+               base (client)
+               {
+               }
+
+               public System.IAsyncResult BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, System.AsyncCallback callback, object asyncState)
+               {
+                       object[] _args = new object[1];
+                       _args [0] = request;
+                       System.IAsyncResult _result = base.BeginInvoke ("FahrenheitToCelsius", _args, callback, asyncState);
+                       return _result;
+               }
+
+               public FahrenheitToCelsiusResponse EndFahrenheitToCelsius (System.IAsyncResult result)
+               {
+                       object[] _args = new object[0];
+                       FahrenheitToCelsiusResponse _result = ((FahrenheitToCelsiusResponse)(base.EndInvoke ("FahrenheitToCelsius", _args, result)));
+                       return _result;
+               }
+
+               public System.IAsyncResult BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, System.AsyncCallback callback, object asyncState)
+               {
+                       object[] _args = new object[1];
+                       _args [0] = request;
+                       System.IAsyncResult _result = base.BeginInvoke ("CelsiusToFahrenheit", _args, callback, asyncState);
+                       return _result;
+               }
+
+               public CelsiusToFahrenheitResponse EndCelsiusToFahrenheit (System.IAsyncResult result)
+               {
+                       object[] _args = new object[0];
+                       CelsiusToFahrenheitResponse _result = ((CelsiusToFahrenheitResponse)(base.EndInvoke ("CelsiusToFahrenheit", _args, result)));
+                       return _result;
+               }
+       }
+}
index 70d9c79c624ff3f6f16f89b274a894da425884f0..cdc68486779adc619e335eccabbb06dc4a72265c 100644 (file)
@@ -57,6 +57,7 @@ namespace MonoTests.System.ServiceModel.Dispatcher
                        serviceHost.AddServiceEndpoint (typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding (), "mex");
 
                        serviceHost.Open ();
+                       Thread.Sleep (2000);  // let WCF spin up
 
                        try {
                                // client
index a7c793bedbfc678d40db6f923a06a29f850939b6..a3147ffc72781bd4149b53ee4dbc5a7890e4fd3d 100644 (file)
@@ -43,6 +43,7 @@ using System.Security.Permissions;
 using System.Collections.Generic;
 using System.Security;
 using System.Threading;
+using Microsoft.Win32.SafeHandles;
 
 namespace System.Diagnostics {
 
@@ -977,15 +978,58 @@ namespace System.Diagnostics {
                        return(ret);
                }
 
-               private static bool Start_noshell (ProcessStartInfo startInfo,
-                                                  Process process)
+               //
+               // Creates a pipe with read and write descriptors
+               //
+               static void CreatePipe (out IntPtr read, out IntPtr write, bool writeDirection)
                {
-                       ProcInfo proc_info=new ProcInfo();
-                       IntPtr stdin_rd = IntPtr.Zero, stdin_wr = IntPtr.Zero;
-                       IntPtr stdout_wr;
-                       IntPtr stderr_wr;
-                       bool ret;
-                       MonoIOError error;
+                       //
+                       // Creates read/write pipe from parent -> child perspective
+                       // a child process uses same descriptors after fork. That's
+                       // 4 descriptors in total where only 2. One in child, one in parent
+                       // should be active and the other 2 closed. Which ones depends on
+                       // comunication direction
+                       //
+                       // parent  -------->  child   (parent can write, child can read)
+                       //
+                       // read: closed       read: used
+                       // write: used        write: closed
+                       //
+                       //
+                       // parent  <--------  child   (parent can read, child can write)
+                       //
+                       // read: used         read: closed
+                       // write: closed      write: used
+                       //
+                       // It can still be tricky for predefined descriptiors http://unixwiz.net/techtips/remap-pipe-fds.html
+                       //
+                       var ret = MonoIO.CreatePipe (out read, out write);
+                       if (!ret)
+                               throw new IOException ("Error creating process pipe");
+
+                       if (IsWindows) {
+                               const int DUPLICATE_SAME_ACCESS = 0x00000002;
+                               var tmp = writeDirection ? write : read;
+
+                               ret = MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, tmp,
+                                       Process.GetCurrentProcess ().Handle, out tmp, 0, 0, DUPLICATE_SAME_ACCESS);
+                               if (!ret)
+                                       return;
+
+                               MonoIOError error;
+                               if (writeDirection) {
+                                       MonoIO.Close (write, out error);
+                                       write = tmp;
+                               } else {
+                                       MonoIO.Close (read, out error);
+                                       read = tmp;
+                               }
+                       }
+               }
+
+               static bool Start_noshell (ProcessStartInfo startInfo, Process process)
+               {
+                       var proc_info = new ProcInfo ();
 
                        if (startInfo.HaveEnvVars) {
                                string [] strs = new string [startInfo.EnvironmentVariables.Count];
@@ -997,164 +1041,118 @@ namespace System.Diagnostics {
                                proc_info.envValues = strs;
                        }
 
-                       if (startInfo.RedirectStandardInput == true) {
-                               if (IsWindows) {
-                                       int DUPLICATE_SAME_ACCESS = 0x00000002;
-                                       IntPtr stdin_wr_tmp;
+                       MonoIOError error;
+                       IntPtr stdin_read = IntPtr.Zero, stdin_write = IntPtr.Zero;
+                       IntPtr stdout_read = IntPtr.Zero, stdout_write = IntPtr.Zero;
+                       IntPtr stderr_read = IntPtr.Zero, stderr_write = IntPtr.Zero;
 
-                                       ret = MonoIO.CreatePipe (out stdin_rd,
-                                                                        out stdin_wr_tmp);
-                                       if (ret) {
-                                               ret = MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, stdin_wr_tmp,
-                                               Process.GetCurrentProcess ().Handle, out stdin_wr, 0, 0, DUPLICATE_SAME_ACCESS);
-                                               MonoIO.Close (stdin_wr_tmp, out error);
-                                       }
-                               }
-                               else
-                               {
-                                       ret = MonoIO.CreatePipe (out stdin_rd,
-                                                                        out stdin_wr);
-                               }
-                               if (ret == false) {
-                                       throw new IOException ("Error creating standard input pipe");
+                       try {
+                               if (startInfo.RedirectStandardInput) {
+                                       CreatePipe (out stdin_read, out stdin_write, true);
+                               } else {
+                                       stdin_read = MonoIO.ConsoleInput;
+                                       stdin_write = IntPtr.Zero;
                                }
-                       } else {
-                               stdin_rd = MonoIO.ConsoleInput;
-                               /* This is required to stop the
-                                * &$*£ing stupid compiler moaning
-                                * that stdin_wr is unassigned, below.
-                                */
-                               stdin_wr = (IntPtr)0;
-                       }
-
-                       if (startInfo.RedirectStandardOutput == true) {
-                               IntPtr out_rd = IntPtr.Zero;
-                               if (IsWindows) {
-                                       IntPtr out_rd_tmp;
-                                       int DUPLICATE_SAME_ACCESS = 0x00000002;
-
-                                       ret = MonoIO.CreatePipe (out out_rd_tmp,
-                                                                        out stdout_wr);
-                                       if (ret) {
-                                               MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, out_rd_tmp,
-                                               Process.GetCurrentProcess ().Handle, out out_rd, 0, 0, DUPLICATE_SAME_ACCESS);
-                                               MonoIO.Close (out_rd_tmp, out error);
-                                       }
+
+                               if (startInfo.RedirectStandardOutput) {
+                                       CreatePipe (out stdout_read, out stdout_write, false);
+                                       process.stdout_rd = stdout_read;
+                               } else {
+                                       process.stdout_rd = IntPtr.Zero;
+                                       stdout_write = MonoIO.ConsoleOutput;
                                }
-                               else {
-                                       ret = MonoIO.CreatePipe (out out_rd,
-                                                                        out stdout_wr);
+
+                               if (startInfo.RedirectStandardError) {
+                                       CreatePipe (out stderr_read, out stderr_write, false);
+                                       process.stderr_rd  = stderr_read;
+                               } else {
+                                       process.stderr_rd = IntPtr.Zero;
+                                       stderr_write = MonoIO.ConsoleError;
                                }
 
-                               process.stdout_rd = out_rd;
-                               if (ret == false) {
-                                       if (startInfo.RedirectStandardInput == true) {
-                                               MonoIO.Close (stdin_rd, out error);
-                                               MonoIO.Close (stdin_wr, out error);
-                                       }
+                               FillUserInfo (startInfo, ref proc_info);
 
-                                       throw new IOException ("Error creating standard output pipe");
+                               //
+                               // FIXME: For redirected pipes we need to send descriptors of
+                               // stdin_write, stdout_read, stderr_read to child process and
+                               // close them there (fork makes exact copy of parent's descriptors)
+                               //
+                               if (!CreateProcess_internal (startInfo, stdin_read, stdout_write, stderr_write, ref proc_info)) {
+                                       throw new Win32Exception (-proc_info.pid, 
+                                       "ApplicationName='" + startInfo.FileName +
+                                       "', CommandLine='" + startInfo.Arguments +
+                                       "', CurrentDirectory='" + startInfo.WorkingDirectory +
+                                       "', Native error= " + Win32Exception.W32ErrorMessage (-proc_info.pid));
                                }
-                       } else {
-                               process.stdout_rd = (IntPtr)0;
-                               stdout_wr = MonoIO.ConsoleOutput;
-                       }
-
-                       if (startInfo.RedirectStandardError == true) {
-                               IntPtr err_rd = IntPtr.Zero;
-                               if (IsWindows) {
-                                       IntPtr err_rd_tmp;
-                                       int DUPLICATE_SAME_ACCESS = 0x00000002;
-
-                                       ret = MonoIO.CreatePipe (out err_rd_tmp,
-                                                                        out stderr_wr);
-                                       if (ret) {
-                                               MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, err_rd_tmp,
-                                               Process.GetCurrentProcess ().Handle, out err_rd, 0, 0, DUPLICATE_SAME_ACCESS);
-                                               MonoIO.Close (err_rd_tmp, out error);
-                                       }
+                       } catch {
+                               if (startInfo.RedirectStandardInput) {
+                                       if (stdin_read != IntPtr.Zero)
+                                               MonoIO.Close (stdin_read, out error);
+                                       if (stdin_write != IntPtr.Zero)
+                                               MonoIO.Close (stdin_write, out error);
                                }
-                               else {
-                                       ret = MonoIO.CreatePipe (out err_rd,
-                                                                        out stderr_wr);
+
+                               if (startInfo.RedirectStandardOutput) {
+                                       if (stdout_read != IntPtr.Zero)
+                                               MonoIO.Close (stdout_read, out error);
+                                       if (stdout_write != IntPtr.Zero)
+                                               MonoIO.Close (stdout_write, out error);
                                }
 
-                               process.stderr_rd = err_rd;
-                               if (ret == false) {
-                                       if (startInfo.RedirectStandardInput == true) {
-                                               MonoIO.Close (stdin_rd, out error);
-                                               MonoIO.Close (stdin_wr, out error);
-                                       }
-                                       if (startInfo.RedirectStandardOutput == true) {
-                                               MonoIO.Close (process.stdout_rd, out error);
-                                               MonoIO.Close (stdout_wr, out error);
-                                       }
-                                       
-                                       throw new IOException ("Error creating standard error pipe");
+                               if (startInfo.RedirectStandardError) {
+                                       if (stderr_read != IntPtr.Zero)
+                                               MonoIO.Close (stderr_read, out error);
+                                       if (stderr_write != IntPtr.Zero)
+                                               MonoIO.Close (stderr_write, out error);
                                }
-                       } else {
-                               process.stderr_rd = (IntPtr)0;
-                               stderr_wr = MonoIO.ConsoleError;
-                       }
 
-                       FillUserInfo (startInfo, ref proc_info);
-                       try {
-                               ret = CreateProcess_internal (startInfo,
-                                                             stdin_rd, stdout_wr, stderr_wr,
-                                                             ref proc_info);
+                               throw;
                        } finally {
-                               if (proc_info.Password != IntPtr.Zero)
+                               if (proc_info.Password != IntPtr.Zero) {
                                        Marshal.ZeroFreeBSTR (proc_info.Password);
-                               proc_info.Password = IntPtr.Zero;
-                       }
-                       if (!ret) {
-                               if (startInfo.RedirectStandardInput == true) {
-                                       MonoIO.Close (stdin_rd, out error);
-                                       MonoIO.Close (stdin_wr, out error);
-                               }
-
-                               if (startInfo.RedirectStandardOutput == true) {
-                                       MonoIO.Close (process.stdout_rd, out error);
-                                       MonoIO.Close (stdout_wr, out error);
-                               }
-
-                               if (startInfo.RedirectStandardError == true) {
-                                       MonoIO.Close (process.stderr_rd, out error);
-                                       MonoIO.Close (stderr_wr, out error);
+                                       proc_info.Password = IntPtr.Zero;
                                }
-
-                               throw new Win32Exception (-proc_info.pid,
-                                       "ApplicationName='" + startInfo.FileName +
-                                       "', CommandLine='" + startInfo.Arguments +
-                                       "', CurrentDirectory='" + startInfo.WorkingDirectory +
-                                       "', Native error= " + Win32Exception.W32ErrorMessage (-proc_info.pid));
                        }
 
                        process.process_handle = proc_info.process_handle;
                        process.pid = proc_info.pid;
                        
-                       if (startInfo.RedirectStandardInput == true) {
-                               MonoIO.Close (stdin_rd, out error);
-                               process.input_stream = new StreamWriter (new MonoSyncFileStream (stdin_wr, FileAccess.Write, true, 8192), Console.Out.Encoding);
-                               process.input_stream.AutoFlush = true;
+                       if (startInfo.RedirectStandardInput) {
+                               //
+                               // FIXME: The descriptor needs to be closed but due to wapi io-layer
+                               // not coping with duplicated descriptors any StandardInput write fails
+                               //
+                               // MonoIO.Close (stdin_read, out error);
+
+#if MOBILE
+                               var stdinEncoding = Encoding.Default;
+#else
+                               var stdinEncoding = Console.InputEncoding;
+#endif
+                               process.input_stream = new StreamWriter (new FileStream (new SafeFileHandle (stdin_write, false), FileAccess.Write, 8192, false), stdinEncoding) {
+                                       AutoFlush = true
+                               };
                        }
 
-                       Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding;
-                       Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding;
+                       if (startInfo.RedirectStandardOutput) {
+                               MonoIO.Close (stdout_write, out error);
+
+                               Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding;
 
-                       if (startInfo.RedirectStandardOutput == true) {
-                               MonoIO.Close (stdout_wr, out error);
-                               process.output_stream = new StreamReader (new MonoSyncFileStream (process.stdout_rd, FileAccess.Read, true, 8192), stdoutEncoding, true, 8192);
+                               process.output_stream = new StreamReader (new FileStream (new SafeFileHandle (stdout_read, false), FileAccess.Read, 8192, false), stdoutEncoding, true, 8192);
                        }
 
-                       if (startInfo.RedirectStandardError == true) {
-                               MonoIO.Close (stderr_wr, out error);
-                               process.error_stream = new StreamReader (new MonoSyncFileStream (process.stderr_rd, FileAccess.Read, true, 8192), stderrEncoding, true, 8192);
+                       if (startInfo.RedirectStandardError) {
+                               MonoIO.Close (stderr_write, out error);
+
+                               Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding;
+
+                               process.error_stream = new StreamReader (new FileStream (new SafeFileHandle (stderr_read, false), FileAccess.Read, 8192, false), stderrEncoding, true, 8192);
                        }
 
                        process.StartExitCallbackIfNeeded ();
 
-                       return(ret);
+                       return true;
                }
 
                // Note that ProcInfo.Password must be freed.
index 27f61b35d0ea775478f504f0b288e67620fa7559..0d2e39ee02baddcd7c5f4743b3c8087a6af1cdc6 100644 (file)
@@ -355,7 +355,21 @@ namespace System.IO {
                        while (!requestStop) {
                                var changes = CreateChangeList (ref newFds);
 
-                               int numEvents = kevent_notimeout (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, IntPtr.Zero);
+                               // We are calling an icall, so have to marshal manually
+                               // Marshal in
+                               int ksize = Marshal.SizeOf<kevent> ();
+                               var changesNative = Marshal.AllocHGlobal (ksize * changes.Length);
+                               for (int i = 0; i < changes.Length; ++i)
+                                       Marshal.StructureToPtr (changes [i], changesNative + (i * ksize), false);
+                               var eventBufferNative = Marshal.AllocHGlobal (ksize * eventBuffer.Length);
+
+                               int numEvents = kevent_notimeout (ref conn, changesNative, changes.Length, eventBufferNative, eventBuffer.Length);
+
+                               // Marshal out
+                               Marshal.FreeHGlobal (changesNative);
+                               for (int i = 0; i < numEvents; ++i)
+                                       eventBuffer [i] = Marshal.PtrToStructure<kevent> (eventBufferNative + (i * ksize));
+                               Marshal.FreeHGlobal (eventBufferNative);
 
                                if (numEvents == -1) {
                                        // Stop () signals us to stop by closing the connection
@@ -367,7 +381,6 @@ namespace System.IO {
 
                                        continue;
                                }
-
                                retries = 0;
 
                                for (var i = 0; i < numEvents; i++) {
@@ -658,8 +671,8 @@ namespace System.IO {
                [DllImport ("libc")]
                extern static int kevent (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, [In] ref timespec time);
 
-               [DllImport ("libc", EntryPoint="kevent")]
-               extern static int kevent_notimeout (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, IntPtr ptr);
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern static int kevent_notimeout (ref int kq, IntPtr ev, int nchanges, IntPtr evtlist, int nevents);
        }
 
        class KeventWatcher : IFileWatcher
diff --git a/mcs/class/System/System.IO/MonoSyncFileStream.cs b/mcs/class/System/System.IO/MonoSyncFileStream.cs
deleted file mode 100644 (file)
index f6dd076..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// 
-// System.IO.MonoSyncFileStream.cs: Synchronous FileStream with
-//     asynchronous BeginRead/Write methods.
-//
-// Authors:
-//     Robert Jordan (robertj@gmx.net)
-//
-// Copyright (C) 2007 Novell, Inc. (http://www.novell.com)
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Runtime.Remoting.Messaging;
-
-namespace System.IO
-{
-       internal class MonoSyncFileStream : FileStream
-       {
-               public MonoSyncFileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize)
-                       : base (handle, access, ownsHandle, bufferSize, false)
-               {
-               }
-
-               delegate void WriteDelegate (byte [] buffer, int offset, int count);
-
-               public override IAsyncResult BeginWrite (byte [] buffer, int offset, int count,
-                                                       AsyncCallback cback, object state)
-               {
-                       if (!CanWrite)
-                               throw new NotSupportedException ("This stream does not support writing");
-
-                       if (buffer == null)
-                               throw new ArgumentNullException ("buffer");
-
-                       if (count < 0)
-                               throw new ArgumentOutOfRangeException ("count", "Must be >= 0");
-
-                       if (offset < 0)
-                               throw new ArgumentOutOfRangeException ("offset", "Must be >= 0");
-
-                       WriteDelegate d = new WriteDelegate (this.Write);
-                       return d.BeginInvoke (buffer, offset, count, cback, state);
-               }
-
-               public override void EndWrite (IAsyncResult asyncResult)
-               {
-                       if (asyncResult == null)
-                               throw new ArgumentNullException ("asyncResult");
-
-                       AsyncResult ar = asyncResult as AsyncResult;
-                       if (ar == null)
-                               throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
-                       WriteDelegate d = ar.AsyncDelegate as WriteDelegate;
-                       if (d == null)
-                               throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
-                       d.EndInvoke (asyncResult);
-               }
-
-               delegate int ReadDelegate (byte [] buffer, int offset, int count);
-
-               public override IAsyncResult BeginRead (byte [] buffer, int offset, int count,
-                                                       AsyncCallback cback, object state)
-               {
-                       if (!CanRead)
-                               throw new NotSupportedException ("This stream does not support reading");
-
-                       if (buffer == null)
-                               throw new ArgumentNullException ("buffer");
-
-                       if (count < 0)
-                               throw new ArgumentOutOfRangeException ("count", "Must be >= 0");
-
-                       if (offset < 0)
-                               throw new ArgumentOutOfRangeException ("offset", "Must be >= 0");
-
-                       ReadDelegate d = new ReadDelegate (this.Read);
-                       return d.BeginInvoke (buffer, offset, count, cback, state);
-               }
-
-               public override int EndRead (IAsyncResult asyncResult)
-               {
-                       if (asyncResult == null)
-                               throw new ArgumentNullException ("asyncResult");
-
-                       AsyncResult ar = asyncResult as AsyncResult;
-                       if (ar == null)
-                               throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
-                       ReadDelegate d = ar.AsyncDelegate as ReadDelegate;
-                       if (d == null)
-                               throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
-                       return d.EndInvoke (asyncResult);
-               }
-
-       }
-}
index addcc28907b34daf68df5df074737ff54133e8f3..b7cc92386f56e22d45233c602cf995a8198daf1a 100644 (file)
@@ -29,6 +29,7 @@
 //
 
 using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Text;
@@ -114,13 +115,13 @@ namespace System.Net
                {
                        int count = chunks.Count;
                        int nread = 0;
+
+                       var chunksForRemoving = new List<Chunk>(count);
                        for (int i = 0; i < count; i++) {
                                Chunk chunk = (Chunk) chunks [i];
-                               if (chunk == null)
-                                       continue;
 
                                if (chunk.Offset == chunk.Bytes.Length) {
-                                       chunks [i] = null;
+                                       chunksForRemoving.Add(chunk);
                                        continue;
                                }
                                
@@ -129,6 +130,9 @@ namespace System.Net
                                        break;
                        }
 
+                       foreach (var chunk in chunksForRemoving)
+                               chunks.Remove(chunk);
+
                        return nread;
                }
                
index bb47c65c48faa262a6dedeeafc554390e796d4cd..d3a3dd507be8c35b0f252f25ea9ad0e1c9cd89a6 100644 (file)
@@ -312,7 +312,7 @@ namespace System.Net
                        lock (this) {
                                idleSince = outIdleSince;
 
-                               if (removeList != null) {
+                               if (removeList != null && groups != null) {
                                        foreach (var group in removeList)
                                                if (groups.ContainsKey (group.Name))
                                                        RemoveConnectionGroup (group);
index 87f60363da8a4306b543420ccf085a142b764d2e..3862b3e4eff56284f11f2d1f768ce139c75e2c02 100644 (file)
@@ -654,7 +654,8 @@ namespace System.Net
                        if (setInternalLength && !no_writestream && writeBuffer != null)
                                request.InternalContentLength = writeBuffer.Length;
 
-                       if (!(sendChunked || request.ContentLength > -1 || no_writestream || webdav))
+                       bool has_content = !no_writestream && (writeBuffer == null || request.ContentLength > -1);
+                       if (!(sendChunked || has_content || no_writestream || webdav))
                                return false;
 
                        headersSent = true;
index 9c4f6cfe4ea87886d10c5c423b6f358964f9230d..83ee323b86bf5e4ed39dc9ddcedffff988df8c8e 100644 (file)
@@ -188,7 +188,6 @@ System.IO/InternalBufferOverflowException.cs
 System.IO/InvalidDataException.cs
 System.IO/IODescriptionAttribute.cs
 System.IO/KeventWatcher.cs
-System.IO/MonoSyncFileStream.cs
 System.IO/NotifyFilters.cs
 System.IO.Ports/Handshake.cs
 System.IO.Ports/ISerialStream.cs
index 3464e0a971a9938dd0fd661294c3678855255e70..6d878731991f60945ebc74a77981c868acf44215 100644 (file)
@@ -263,7 +263,12 @@ namespace System
 
                        builder.Append (scheme);
                        // note: mailto and news use ':', not "://", as their delimiter
-                       builder.Append (Uri.GetSchemeDelimiter (scheme));
+                       if (UriParser.IsKnownScheme(scheme)) {
+                               builder.Append (Uri.GetSchemeDelimiter (scheme));
+                       }
+                       else {
+                               builder.Append (host.Length > 0 ? Uri.SchemeDelimiter : ":");
+                       }
 
                        if (username != String.Empty) {
                                builder.Append (username);
@@ -280,7 +285,8 @@ namespace System
 
                        if (path != String.Empty &&
                            builder [builder.Length - 1] != '/' &&
-                           path.Length > 0 && path [0] != '/')
+                           path.Length > 0 && path [0] != '/' &&
+                               host.Length > 0)
                                builder.Append ('/');
                        builder.Append (path);
                        builder.Append (query);
index 0a316e34494d96dc0e468a39d7dfee56188f83c8..d4372a1ddddc76083a6022ab54d46aa4212ec533 100644 (file)
@@ -732,8 +732,6 @@ namespace MonoTests.System.Diagnostics
 
                public int bytesRead = -1;
 
-// Not technically a 2.0 only test, but I use lambdas, so I need gmcs
-
                [Test]
                [NUnit.Framework.Category ("MobileNotWorking")]
                // This was for bug #459450
@@ -791,9 +789,11 @@ namespace MonoTests.System.Diagnostics
                        p.StartInfo.RedirectStandardError = true;
 
                        var exitedCalledCounter = 0;
+                       var exited = new ManualResetEventSlim ();
                        p.Exited += (object sender, EventArgs e) => {
                                exitedCalledCounter++;
                                Assert.IsTrue (p.HasExited);
+                               exited.Set ();
                        };
 
                        p.EnableRaisingEvents = true;
@@ -803,6 +803,7 @@ namespace MonoTests.System.Diagnostics
                        p.BeginOutputReadLine ();
                        p.WaitForExit ();
 
+                       exited.Wait (10000);
                        Assert.AreEqual (1, exitedCalledCounter);
                        Thread.Sleep (50);
                        Assert.AreEqual (1, exitedCalledCounter);
@@ -822,9 +823,11 @@ namespace MonoTests.System.Diagnostics
                        p.EnableRaisingEvents = true;
 
                        var exitedCalledCounter = 0;
+                       var exited = new ManualResetEventSlim ();
                        p.Exited += (object sender, EventArgs e) => {
                                exitedCalledCounter++;
                                Assert.IsTrue (p.HasExited);
+                               exited.Set ();
                        };
 
                        p.Start ();
@@ -832,6 +835,7 @@ namespace MonoTests.System.Diagnostics
                        p.BeginOutputReadLine ();
                        p.WaitForExit ();
 
+                       exited.Wait (10000);
                        Assert.AreEqual (1, exitedCalledCounter);
                        Thread.Sleep (50);
                        Assert.AreEqual (1, exitedCalledCounter);
@@ -934,6 +938,21 @@ namespace MonoTests.System.Diagnostics
                        p.Dispose ();
                }
 
+               [Test]
+               [NUnit.Framework.Category ("MobileNotWorking")]
+               public void StandardInputWrite ()
+               {
+                       var psi = GetCrossPlatformStartInfo ();
+                       psi.RedirectStandardInput = true;
+                       psi.RedirectStandardOutput = true;
+                       psi.UseShellExecute = false;
+
+                       using (var p = Process.Start (psi)) {
+                               for (int i = 0; i < 1024 * 9; ++i)
+                                       p.StandardInput.Write ('x');
+                       }
+               }
+
                [Test]
                public void Modules () {
                        var modules = Process.GetCurrentProcess ().Modules;
index 3f3cf1a5ddbae5c2480959728273167dc5c85f25..2dd0d0674632ab82bd8a73d99724e3f1cc9c43b3 100644 (file)
@@ -77,9 +77,9 @@ public class SslStreamTest {
                        serverThread.Start ();
                        Thread clientThread = new Thread (() => StartClientAndAuthenticate (state, endPoint));
                        clientThread.Start ();
-                       Assert.AreEqual (server, state.ServerAuthenticated.WaitOne (TimeSpan.FromSeconds (2)), 
+                       Assert.AreEqual (server, state.ServerAuthenticated.WaitOne (TimeSpan.FromSeconds (5)), 
                                "server not authenticated");
-                       Assert.AreEqual (client, state.ClientAuthenticated.WaitOne (TimeSpan.FromSeconds (2)), 
+                       Assert.AreEqual (client, state.ClientAuthenticated.WaitOne (TimeSpan.FromSeconds (5)), 
                                "client not authenticated");
                } finally {
                        if (state.ClientStream != null)
index 7422a1f2695dc2e345220d5736974c5223a40a4e..715c748d1f5fe0cb703014e012db8fce842f0993 100644 (file)
@@ -48,7 +48,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void ServerHandshakeReturnCrapStatusCodeTest ()
                {
                        // On purpose, 
@@ -65,7 +65,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void ServerHandshakeReturnWrongUpgradeHeader ()
                {
                        #pragma warning disable 4014
@@ -84,7 +84,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void ServerHandshakeReturnWrongConnectionHeader ()
                {
                        #pragma warning disable 4014
@@ -105,7 +105,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // The test hangs when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // The test hangs when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void EchoTest ()
                {
                        const string Payload = "This is a websocket test";
@@ -130,7 +130,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void CloseOutputAsyncTest ()
                {
                        Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
@@ -147,7 +147,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void CloseAsyncTest ()
                {
                        Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
@@ -164,7 +164,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test, ExpectedException (typeof (ArgumentNullException))]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void SendAsyncArgTest_NoArray ()
                {
                        Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
@@ -178,7 +178,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test, ExpectedException (typeof (ArgumentNullException))]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void ReceiveAsyncArgTest_NoArray ()
                {
                        Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
@@ -186,7 +186,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void ReceiveAsyncWrongState_Closed ()
                {
                        try {
@@ -201,7 +201,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void SendAsyncWrongState_Closed ()
                {
                        try {
@@ -216,7 +216,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void SendAsyncWrongState_CloseSent ()
                {
                        try {
index d2c19e49830c1b32663bc58d826a8ef85776645b..a01e0accc2fb580acd4c5e279ea39f8b7b7625c3 100644 (file)
@@ -383,6 +383,13 @@ namespace MonoTests.System
                        // this is what ASP.NET really means (the ?)
                        Assert.AreEqual ("http://192.168.0.21/error404.aspx?aspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
                }
+
+               [Test]
+               public void NoHostname ()
+               {
+                       UriBuilder ub = new UriBuilder ("about", null, -1, "config");
+                       Assert.AreEqual ("about:config", ub.ToString ());
+               }
        }
 }
 
index f5ec7ca294b3d8550ff50036deccb8bf8e20572c..06d36fe18732550de466b65ff537e447867efb0f 100644 (file)
@@ -28,7 +28,6 @@ System.IO.Compression/DeflateStream.cs
 System.IO.Compression/GZipStream.cs
 System.IO/InternalBufferOverflowException.cs
 System.IO/InvalidDataException.cs
-System.IO/MonoSyncFileStream.cs
 System.Net.Cache/HttpCacheAgeControl.cs
 System.Net.Cache/HttpRequestCacheLevel.cs
 System.Net.Cache/HttpRequestCachePolicy.cs
index d6586ab4d5e18d7b349e5e0e04a99fa9d29e7805..06546720d6ca05c20fefb65c31797a4ed3d62fa1 100644 (file)
@@ -125,7 +125,8 @@ namespace System.IO.Packaging {
 
                private PackageRelationship CreateRelationship (Uri targetUri, TargetMode targetMode, string relationshipType, string id, bool loading)
                {
-                       Package.CheckIsReadOnly ();
+                       if (!loading)
+                               Package.CheckIsReadOnly ();
                        Check.TargetUri (targetUri);
                        Check.RelationshipTypeIsValid (relationshipType);
                        Check.IdIsValid (id);
index ad7eb968c3ad5bce626e29b73d8698c86e56d54a..06ed852c52b75c8eceadeb48865aa69da6b99c1b 100644 (file)
@@ -369,5 +369,19 @@ namespace MonoTests.System.IO.Packaging {
         {\r
                Assert.IsFalse (package.PartExists(new Uri ("[Content_Types].xml", UriKind.Relative)));\r
         }\r
+\r
+        [Test]\r
+        public void CheckCanGetRelationshipsIfReadOnly ()\r
+        {\r
+            using (var stream = new MemoryStream ()) {\r
+                var package = Package.Open (stream, FileMode.OpenOrCreate);\r
+                var part = package.CreatePart (uris [0], contentType);\r
+                part.CreateRelationship (part.Uri, TargetMode.Internal, "self");\r
+                package.Close ();\r
+                package = Package.Open (new MemoryStream (stream.ToArray ()), FileMode.Open, FileAccess.Read);\r
+                part = package.GetPart (uris [0]);\r
+                part.GetRelationships ();\r
+            }\r
+        }\r
     }\r
 }\r
index 53538b65e8d54c5a002f652cf4b7249847ecc562..5811cdc8337644fa162986abd2fef1e79988e376 100644 (file)
@@ -4,14 +4,6 @@ namespace System.Globalization
 {
        partial class TextInfo
        {
-               unsafe static ushort *to_lower_data_low;
-               unsafe static ushort *to_lower_data_high;
-               unsafe static ushort *to_upper_data_low;
-               unsafe static ushort *to_upper_data_high;
-
-               [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
-               unsafe static extern void GetDataTablePointersLite (out ushort *to_lower_data_low, out ushort *to_lower_data_high, out ushort *to_upper_data_low, out ushort *to_upper_data_high);
-
                unsafe string ToUpperInternal (string str)
                {
                        if (str.Length == 0)
index 3e775808fdc04a97de3a8adc125948cd2f9b4d7d..e66221766c995169c191024e16b020be1e95378f 100644 (file)
@@ -57,6 +57,7 @@ namespace System.Diagnostics {
                public const int METHODS_TO_SKIP = 0;
 
                private StackFrame[] frames;
+               readonly StackTrace[] captured_traces;
                private bool debug_info;
 
                public StackTrace ()
@@ -119,11 +120,6 @@ namespace System.Diagnostics {
                }
 
                public StackTrace (Exception e, int skipFrames, bool fNeedFileInfo)
-                       : this (e, skipFrames, fNeedFileInfo, false)
-               {
-               }
-
-               internal StackTrace (Exception e, int skipFrames, bool fNeedFileInfo, bool returnNativeFrames)
                {
                        if (e == null)
                                throw new ArgumentNullException ("e");
@@ -132,22 +128,7 @@ namespace System.Diagnostics {
 
                        frames = get_trace (e, skipFrames, fNeedFileInfo);
 
-                       if (!returnNativeFrames) {
-                               bool resize = false;
-                               for (int i = 0; i < frames.Length; ++i)
-                                       if (frames [i].GetMethod () == null)
-                                               resize = true;
-
-                               if (resize) {
-                                       var l = new List<StackFrame> ();
-
-                                       for (int i = 0; i < frames.Length; ++i)
-                                               if (frames [i].GetMethod () != null)
-                                                       l.Add (frames [i]);
-
-                                       frames = l.ToArray ();
-                               }
-                       }
+                       captured_traces = e.captured_traces;
                }
 
                public StackTrace (StackFrame frame)
@@ -189,7 +170,7 @@ namespace System.Diagnostics {
                        return frames;
                }
 
-               internal bool AddFrames (StringBuilder sb, bool isException = false)
+               bool AddFrames (StringBuilder sb, bool isException = false)
                {
                        bool printOffset;
                        string debugInfo, indentation;
@@ -306,6 +287,21 @@ namespace System.Diagnostics {
                public override string ToString ()
                {
                        StringBuilder sb = new StringBuilder ();
+
+                       //
+                       // Add traces captured using ExceptionDispatchInfo
+                       //
+                       if (captured_traces != null) {
+                               foreach (var t in captured_traces) {
+                                       if (!t.AddFrames (sb, true))
+                                               continue;
+
+                                       sb.Append (Environment.NewLine);
+                                       sb.Append ("--- End of stack trace from previous location where exception was thrown ---");
+                                       sb.Append (Environment.NewLine);
+                               }
+                       }
+
                        AddFrames (sb);
                        return sb.ToString ();
                }
index 5690dac24ed8f814ff12c3471e1cc5bd3a9401f1..9de058fbb3a3a42800baa9f25b84bb13b948515a 100644 (file)
@@ -73,12 +73,12 @@ namespace System.IO
                        : this (handle, access, ownsHandle, bufferSize, isAsync, false) {}
 
                [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
-               internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isZeroSize)
+               internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isConsoleWrapper)
                {
                        if (handle == MonoIO.InvalidHandle)
                                throw new ArgumentException ("handle", Locale.GetText ("Invalid."));
 
-                       Init (new SafeFileHandle (handle, false), access, ownsHandle, bufferSize, isAsync, isZeroSize);
+                       Init (new SafeFileHandle (handle, false), access, ownsHandle, bufferSize, isAsync, isConsoleWrapper);
                }
 
                // construct from filename
@@ -113,7 +113,6 @@ namespace System.IO
                {
                }
 
-#if !NET_2_1
                public FileStream (SafeFileHandle handle, FileAccess access)
                        :this(handle, access, DefaultBufferSize, false)
                {
@@ -130,6 +129,7 @@ namespace System.IO
                        Init (handle, access, false, bufferSize, isAsync, false);
                }
 
+#if !MOBILE
                [MonoLimitation ("This ignores the rights parameter")]
                public FileStream (string path, FileMode mode,
                                   FileSystemRights rights, FileShare share,
@@ -291,10 +291,14 @@ namespace System.IO
                        }
                }
 
-               private void Init (SafeFileHandle safeHandle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isZeroSize)
+               private void Init (SafeFileHandle safeHandle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isConsoleWrapper)
                {
+                       if (!isConsoleWrapper && safeHandle.IsInvalid)
+                               throw new ArgumentException(Environment.GetResourceString("Arg_InvalidHandle"), "handle");
                        if (access < FileAccess.Read || access > FileAccess.ReadWrite)
                                throw new ArgumentOutOfRangeException ("access");
+                       if (!isConsoleWrapper && bufferSize <= 0)
+                               throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
 
                        MonoIOError error;
                        MonoFileType ftype = MonoIO.GetFileType (safeHandle, out error);
diff --git a/mcs/class/corlib/System.IO/IntPtrStream.cs b/mcs/class/corlib/System.IO/IntPtrStream.cs
deleted file mode 100644 (file)
index 40b1c58..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-//
-// System.IO.IntPtrStream: A stream that is backed up by unmanaged memory
-//
-// Author:
-//   Miguel de Icaza (miguel@ximian.com)
-//
-// Based on the code for MemoryStream.cs:
-//
-// Authors:    Marcin Szczepanski (marcins@zipworld.com.au)
-//             Patrik Torstensson
-//             Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//
-// (c) 2001,2002 Marcin Szczepanski, Patrik Torstensson
-// (c) 2003 Ximian, Inc. (http://www.ximian.com)
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Runtime.InteropServices;
-namespace System.IO {
-
-       internal class IntPtrStream : Stream {
-               unsafe byte *base_address;
-               int size;
-               int position;
-               bool closed;
-
-               public event EventHandler Closed;
-               
-               public IntPtrStream (IntPtr base_address, int size)
-               {
-                       unsafe {
-                               this.base_address = (byte*)((void *)base_address);
-                       }
-                       this.size = size;
-                       position = 0;
-               }
-
-               internal IntPtr BaseAddress {
-                       get {
-                               unsafe {
-                                       return new IntPtr ((void*) base_address);
-                               }
-                       }
-               }
-
-               public override bool CanRead {
-                       get {
-                               return true;
-                       }
-               }
-
-               public override bool CanSeek {
-                       get {
-                               return true;
-                       }
-               }
-
-               public override bool CanWrite {
-                       get {
-                               return false;
-                       }
-               }
-
-               public override long Position {
-                       get {
-                               return position;
-                       }
-
-                       set {
-                               if (position < 0)
-                                       throw new ArgumentOutOfRangeException ("Position", "Can not be negative");
-                               if (position > size)
-                                       throw new ArgumentOutOfRangeException ("Position", "Pointer falls out of range");
-
-                               position = (int) value;
-                       }
-               }
-
-               public override long Length {
-                       get {
-                               return size;
-                       }
-               }
-
-               public override int Read (byte [] buffer, int offset, int count)
-               {
-                       if (buffer == null)
-                               throw new ArgumentNullException ("buffer");
-
-                       if (offset < 0 || count < 0)
-                               throw new ArgumentOutOfRangeException ("offset or count less than zero.");
-
-                       if (buffer.Length - offset < count )
-                               throw new ArgumentException ("offset+count",
-                                                             "The size of the buffer is less than offset + count.");
-
-                       if (closed)
-                               throw new ObjectDisposedException ("Stream has been closed");
-
-                       if (position >= size || count == 0)
-                               return 0;
-
-                       if (position > size - count)
-                               count = size - position;
-
-                       unsafe {
-                               Marshal.Copy ((IntPtr) (base_address + position), buffer, offset, count);
-                       }
-                       position += count;
-                       return count;
-               }
-
-               public override int ReadByte ()
-               {
-                       if (position >= size)
-                               return -1;
-
-                       if (closed)
-                               throw new ObjectDisposedException ("Stream has been closed");
-
-                       unsafe {
-                               return base_address [position++];
-                       }
-               }
-
-               public override long Seek (long offset, SeekOrigin loc)
-               {
-                       // It's funny that they don't throw this exception for < Int32.MinValue
-                       if (offset > (long) Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("Offset out of range. " + offset);
-
-                       if (closed)
-                               throw new ObjectDisposedException ("Stream has been closed");
-
-                       int ref_point;
-                       switch (loc) {
-                       case SeekOrigin.Begin:
-                               if (offset < 0)
-                                       throw new IOException ("Attempted to seek before start of MemoryStream.");
-                               ref_point = 0;
-                               break;
-                       case SeekOrigin.Current:
-                               ref_point = position;
-                               break;
-                       case SeekOrigin.End:
-                               ref_point = size;
-                               break;
-                       default:
-                               throw new ArgumentException ("loc", "Invalid SeekOrigin");
-                       }
-
-                       checked {
-                               try {
-                                       ref_point += (int) offset;
-                               } catch {
-                                       throw new ArgumentOutOfRangeException ("Too large seek destination");
-                               }
-                               
-                               if (ref_point < 0)
-                                       throw new IOException ("Attempted to seek before start of MemoryStream.");
-                       }
-
-                       position = ref_point;
-                       return position;
-               }
-               
-               public override void SetLength (long value)
-               {
-                       throw new NotSupportedException ("This stream can not change its size");
-               }
-
-               public override void Write (byte [] buffer, int offset, int count)
-               {
-                       throw new NotSupportedException ("This stream can not change its size");
-               }
-
-               public override void WriteByte (byte value)
-               {
-                       throw new NotSupportedException ("This stream can not change its size");
-               }
-               
-               public override void Flush ()
-               {
-               }
-
-               public override void Close ()
-               {
-                       closed = true;
-
-                       if (Closed != null)
-                               Closed (this, null);
-               }
-       }
-}
index e195b080e88a46caf773b94523756541894c0c7b..9d816f40a5952a5e7edcb570a187b34eec2d5427 100644 (file)
@@ -599,9 +599,6 @@ namespace System.IO
                        [MethodImplAttribute (MethodImplOptions.InternalCall)]
                        get;
                }
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static int GetTempPath(out string path);
        }
 }
 
index b87647cd80e69dc2ed2f3dbd3025b5238b12d8e2..876de83bff0a9c2a5758d2d4f3babd590c34e9b9 100644 (file)
@@ -69,12 +69,28 @@ namespace System.Reflection {
                        }
                }
 
+               public override Module Module {
+                       get {
+                               return GetRuntimeModule ();
+                       }
+               }
+
+               internal RuntimeType GetDeclaringTypeInternal ()
+               {
+                       return (RuntimeType) DeclaringType;
+               }
+
                RuntimeType ReflectedTypeInternal {
                        get {
                                return (RuntimeType) ReflectedType;
                        }
                }
 
+               internal RuntimeModule GetRuntimeModule ()
+               {
+                       return GetDeclaringTypeInternal ().GetRuntimeModule ();
+               }
+
         #region ISerializable
         public void GetObjectData(SerializationInfo info, StreamingContext context)
         {
index 0f28d20d5c7fac4cb79f68ba57c325e193aff128..87310b19e2fa8d22835a84f4e05b3d75e0d9b932 100644 (file)
@@ -82,12 +82,28 @@ namespace System.Reflection {
                        }
                }
 
+               public override Module Module {
+                       get {
+                               return GetRuntimeModule ();
+                       }
+               }
+
+               internal RuntimeType GetDeclaringTypeInternal ()
+               {
+                       return (RuntimeType) DeclaringType;
+               }
+
                RuntimeType ReflectedTypeInternal {
                        get {
                                return (RuntimeType) ReflectedType;
                        }
                }
 
+               internal RuntimeModule GetRuntimeModule ()
+               {
+                       return GetDeclaringTypeInternal ().GetRuntimeModule ();
+               }
+
         #region Object Overrides
         public override String ToString()
         {
index 026f46c3797430f24db8ba3911b8a03bd84749fd..c5cda6920d2edc3729e325bd3228629350ef94ae 100644 (file)
@@ -192,9 +192,14 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static void try_enter_with_atomic_var (object obj, int millisecondsTimeout, ref bool lockTaken);
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern static void enter_with_atomic_var (object obj, ref bool lockTaken);
+
+               // Can't make this an icall since it has the same name as the other Enter method
+               [MethodImpl(MethodImplOptions.AggressiveInlining)]
                public static void Enter (object obj, ref bool lockTaken)
                {
-                       TryEnter (obj, Timeout.Infinite, ref lockTaken);
+                       enter_with_atomic_var (obj, ref lockTaken);
                }
 
                public static void TryEnter (object obj, ref bool lockTaken)
diff --git a/mcs/class/corlib/System.Threading/ThreadPool.cs b/mcs/class/corlib/System.Threading/ThreadPool.cs
deleted file mode 100644 (file)
index eb01abf..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-//
-// System.Threading.ThreadPool.cs
-//
-// Author:
-//   Patrik Torstensson
-//   Dick Porter (dick@ximian.com)
-//   Maurer Dietmar (dietmar@ximian.com)
-//
-// (C) Ximian, Inc.  http://www.ximian.com
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Runtime.Remoting.Messaging;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Security.Permissions;
-
-namespace System.Threading {
-
-       public static class ThreadPool {
-
-               [Obsolete("This method is obsolete, use BindHandle(SafeHandle) instead")]
-               public static bool BindHandle (IntPtr osHandle)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.BindHandle (osHandle);
-                       else
-                               return true;
-               }
-
-               public static bool BindHandle (SafeHandle osHandle)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
-                               return Microsoft.ThreadPool.BindHandle (osHandle);
-                       } else {
-                               if (osHandle == null)
-                                       throw new ArgumentNullException ("osHandle");
-                       
-                               return true;
-                       }
-               }
-
-               public static void GetAvailableThreads (out int workerThreads, out int completionPortThreads)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               Microsoft.ThreadPool.GetAvailableThreads (out workerThreads, out completionPortThreads);
-                       else
-                               GetAvailableThreads_internal (out workerThreads, out completionPortThreads);
-               }
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern void GetAvailableThreads_internal (out int workerThreads, out int completionPortThreads);
-
-               public static void GetMaxThreads (out int workerThreads, out int completionPortThreads)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               Microsoft.ThreadPool.GetMaxThreads (out workerThreads, out completionPortThreads);
-                       else
-                               GetMaxThreads_internal (out workerThreads, out completionPortThreads);
-               }
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern void GetMaxThreads_internal (out int workerThreads, out int completionPortThreads);
-
-               public static void GetMinThreads (out int workerThreads, out int completionPortThreads)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               Microsoft.ThreadPool.GetMinThreads (out workerThreads, out completionPortThreads);
-                       else
-                               GetMinThreads_internal (out workerThreads, out completionPortThreads);
-               }
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern void GetMinThreads_internal (out int workerThreads, out int completionPortThreads);
-
-               [MonoTODO("The min number of completion port threads is not evaluated.")]
-               [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
-               public static bool SetMinThreads (int workerThreads, int completionPortThreads)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.SetMinThreads (workerThreads, completionPortThreads);
-                       else
-                               return SetMinThreads_internal (workerThreads, completionPortThreads);
-               }
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern bool SetMinThreads_internal (int workerThreads, int completionPortThreads);
-
-               [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
-               public static bool SetMaxThreads (int workerThreads, int completionPortThreads)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.SetMaxThreads (workerThreads, completionPortThreads);
-                       else
-                               return SetMaxThreads_internal (workerThreads, completionPortThreads);
-               }
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern bool SetMaxThreads_internal (int workerThreads, int completionPortThreads);
-
-               public static bool QueueUserWorkItem (WaitCallback callBack)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.QueueUserWorkItem (callBack, null);
-                       else
-                               return QueueUserWorkItem (callBack, null);
-               }
-
-               public static bool QueueUserWorkItem (WaitCallback callBack, object state)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
-                               return Microsoft.ThreadPool.QueueUserWorkItem (callBack, state);
-                       } else {
-                               if (callBack == null)
-                                       throw new ArgumentNullException ("callBack");
-
-                               if (callBack.IsTransparentProxy ()) {
-                                       IAsyncResult ar = callBack.BeginInvoke (state, null, null);
-                                       if (ar == null)
-                                               return false;
-                               } else {
-                                       AsyncResult ares = new AsyncResult (callBack, state, !ExecutionContext.IsFlowSuppressed());
-                                       pool_queue (ares);
-                               }
-                               return true;
-                       }
-               }
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern void pool_queue (AsyncResult ares);
-
-               // TODO: It should be interface interface only to avoid extra allocation
-               internal static void QueueWorkItem (WaitCallback callBack, object state)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               Microsoft.ThreadPool.QueueUserWorkItem (callBack, state);
-                       else
-                               pool_queue (new AsyncResult (callBack, state, false));
-               }
-
-               public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-                                                                               WaitOrTimerCallback callBack,
-                                                                               object state,
-                                                                               int millisecondsTimeOutInterval,
-                                                                               bool executeOnlyOnce)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
-                       else
-                               return RegisterWaitForSingleObject (waitObject, callBack, state, (long) millisecondsTimeOutInterval, executeOnlyOnce);
-               }
-
-               public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-                                                                               WaitOrTimerCallback callBack,
-                                                                               object state,
-                                                                               long millisecondsTimeOutInterval,
-                                                                               bool executeOnlyOnce)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
-                               return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
-                       } else {
-                               if (waitObject == null)
-                                       throw new ArgumentNullException ("waitObject");
-
-                               if (callBack == null)
-                                       throw new ArgumentNullException ("callBack");
-                       
-                               if (millisecondsTimeOutInterval < -1)
-                                       throw new ArgumentOutOfRangeException ("timeout", "timeout < -1");
-
-                               if (millisecondsTimeOutInterval > Int32.MaxValue)
-                                       throw new NotSupportedException ("Timeout is too big. Maximum is Int32.MaxValue");
-
-                               TimeSpan timeout = new TimeSpan (0, 0, 0, 0, (int) millisecondsTimeOutInterval);
-                       
-                               RegisteredWaitHandle waiter = new RegisteredWaitHandle (waitObject, callBack, state,
-                                                                                       timeout, executeOnlyOnce);
-                               QueueUserWorkItem (new WaitCallback (waiter.Wait), null);
-                               return waiter;
-                       }
-               }
-
-               public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-                                                                               WaitOrTimerCallback callBack,
-                                                                               object state,
-                                                                               TimeSpan timeout,
-                                                                               bool executeOnlyOnce)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, timeout, executeOnlyOnce);
-                       else
-                               return RegisterWaitForSingleObject (waitObject, callBack, state, (long) timeout.TotalMilliseconds, executeOnlyOnce);
-
-               }
-
-               [CLSCompliant(false)]
-               public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-                                                                               WaitOrTimerCallback callBack,
-                                                                               object state,
-                                                                               uint millisecondsTimeOutInterval,
-                                                                               bool executeOnlyOnce)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
-                       else
-                               return RegisterWaitForSingleObject (waitObject, callBack, state, (long) millisecondsTimeOutInterval, executeOnlyOnce);
-               }
-
-               [CLSCompliant (false)]
-               unsafe public static bool UnsafeQueueNativeOverlapped (NativeOverlapped *overlapped)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.UnsafeQueueNativeOverlapped (overlapped);
-                       else
-                               throw new NotImplementedException ();
-               }
-
-#if !NET_2_1 || MOBILE
-
-               [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
-               public static bool UnsafeQueueUserWorkItem (WaitCallback callBack, object state)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
-                               return Microsoft.ThreadPool.UnsafeQueueUserWorkItem (callBack, state);
-                       } else {
-                               if (callBack == null)
-                                       throw new ArgumentNullException ("callBack");
-
-                               // no stack propagation here (that's why it's unsafe and requires extra security permissions)
-                               if (!callBack.IsTransparentProxy ()) {
-                                       AsyncResult ares = new AsyncResult (callBack, state, false);
-                                       pool_queue (ares);
-                                       return true;
-                               }
-                               try {
-                                       if (!ExecutionContext.IsFlowSuppressed ())
-                                               ExecutionContext.SuppressFlow (); // on current thread only
-                                       IAsyncResult ar = callBack.BeginInvoke (state, null, null);
-                                       if (ar == null)
-                                               return false;
-                               } finally {
-                                       if (ExecutionContext.IsFlowSuppressed ())
-                                               ExecutionContext.RestoreFlow ();
-                               }
-                               return true;
-                       }
-               }
-               
-               [MonoTODO("Not implemented")]
-               [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
-               public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
-                       WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval,
-                       bool executeOnlyOnce) 
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
-                       else
-                               throw new NotImplementedException ();
-               }
-               
-               [MonoTODO("Not implemented")]
-               [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
-               public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
-                       WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval,
-                       bool executeOnlyOnce) 
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
-                       else
-                               throw new NotImplementedException ();
-               }
-
-               [MonoTODO("Not implemented")]
-               [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
-               public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
-                       WaitOrTimerCallback callBack, object state, TimeSpan timeout,
-                       bool executeOnlyOnce) 
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, timeout, executeOnlyOnce);
-                       else
-                               throw new NotImplementedException ();
-               }
-
-               [MonoTODO("Not implemented")]
-               [CLSCompliant (false)]
-               [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
-               public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
-                       WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval,
-                       bool executeOnlyOnce) 
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
-                       else
-                               throw new NotImplementedException ();
-               }
-
-#endif
-
-#region ReferenceSources
-               // Extracted from ../../../../external/referencesource/mscorlib/system/threading/threadpool.cs
-               internal static void UnsafeQueueCustomWorkItem(IThreadPoolWorkItem workItem, bool forceGlobal)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               Microsoft.ThreadPool.UnsafeQueueCustomWorkItem (workItem, forceGlobal);
-                       else
-                               QueueWorkItem ((obj) => ((IThreadPoolWorkItem)obj).ExecuteWorkItem (), workItem);
-               }
-
-               internal static IEnumerable<IThreadPoolWorkItem> GetQueuedWorkItems()
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.GetQueuedWorkItems ();
-                       else
-                               return new IThreadPoolWorkItem [0];
-               }
-
-               internal static bool TryPopCustomWorkItem(IThreadPoolWorkItem workItem)
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               return Microsoft.ThreadPool.TryPopCustomWorkItem (workItem);
-                       else
-                               return false;
-               }
-
-               internal static void NotifyWorkItemProgress()
-               {
-                       if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
-                               Microsoft.ThreadPool.NotifyWorkItemProgress ();
-               }
-#endregion
-       }
-}
index deb3eaf4bf76735cd197474d7f5775dcfda30b09..99c5236a7ddf1a7f587168c4f624b3918b87e1a9 100644 (file)
@@ -210,7 +210,8 @@ namespace System
                private static Stream Open (IntPtr handle, FileAccess access, int bufferSize)
                {
                        try {
-                               return new FileStream (handle, access, false, bufferSize, false, bufferSize == 0);
+                               // TODO: Should use __ConsoleStream from reference sources
+                               return new FileStream (handle, access, false, bufferSize, false, true);
                        } catch (IOException) {
                                return Stream.Null;
                        }
index c6b01d789c92fb67ef1b4e0e4a7bcdd8d000caa1..81cad6caa28da0b0d63223001a93013b2d172e48 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 135;
+               private const int mono_corlib_version = 136;
 #pragma warning restore 169
 
                [ComVisible (true)]
index 7670ce338e693a9c88343b870db8fb51d178ac95..e07d2e85b62917446160a44c05574c47afa90d0f 100644 (file)
@@ -69,6 +69,7 @@ namespace System
                IDictionary _data;
                internal StackTrace[] captured_traces;
                IntPtr[] native_trace_ips;
+               object dynamic_methods;
                #endregion
 #pragma warning restore 169, 649
 
@@ -199,26 +200,8 @@ namespace System
                                        /* Not thrown yet */
                                        return null;
 
-                               StringBuilder sb = new StringBuilder ();
-
-                               // Add traces captured using ExceptionDispatchInfo
-                               if (captured_traces != null) {
-                                       foreach (var t in captured_traces) {
-                                               if (!t.AddFrames (sb, true))
-                                                       continue;
-
-                                               sb.Append (Environment.NewLine);
-                                               sb.Append ("--- End of stack trace from previous location where exception was thrown ---");
-                                               sb.Append (Environment.NewLine);
-                                       }
-                               }
-
-                               StackTrace st = new StackTrace (this, 0, true, true);
-                               st.AddFrames (sb, true);
-
-                               stack_trace = sb.ToString ();
-
-                               return stack_trace;
+                               StackTrace st = new StackTrace (this, 0, true);
+                               return stack_trace = st.ToString ();
                        }
                }
 
@@ -316,6 +299,7 @@ namespace System
                {
                        captured_traces = (StackTrace[]) exceptionDispatchInfo.BinaryStackTraceArray;
                        trace_ips = null;
+                       stack_trace = null;
                }
 
                //
diff --git a/mcs/class/corlib/System/Math.cs b/mcs/class/corlib/System/Math.cs
deleted file mode 100644 (file)
index 3ba4b62..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-//
-// System.Math.cs
-//
-// Authors:
-//   Bob Smith (bob@thestuff.net)
-//   Dan Lewis (dihlewis@yahoo.co.uk)
-//   Pedro Martínez Juliá (yoros@wanadoo.es)
-//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
-//
-// (C) 2001 Bob Smith.  http://www.thestuff.net
-// Copyright (C) 2003 Pedro Martínez Juliá <yoros@wanadoo.es>
-// Copyright (C) 2004 Novell (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Runtime.CompilerServices;
-using System.Runtime.ConstrainedExecution;
-
-namespace System
-{
-       public static class Math
-       {
-               public const double E = 2.7182818284590452354;
-               public const double PI = 3.14159265358979323846;
-
-               public static decimal Abs (decimal value)
-               {
-                       return (value < 0)? -value: value;
-               }
-
-               public static double Abs (double value)
-               {
-                       return (value < 0)? -value: value;
-               }
-
-               public static float Abs (float value)
-               {
-                       return (value < 0)? -value: value;
-               }
-
-               public static int Abs (int value)
-               {
-                       if (value == Int32.MinValue)
-                               throw new OverflowException (Locale.GetText ("Value is too small."));
-                       return (value < 0)? -value: value;
-               }
-
-               public static long Abs (long value)
-               {
-                       if (value == Int64.MinValue)
-                               throw new OverflowException (Locale.GetText ("Value is too small."));
-                       return (value < 0)? -value: value;
-               }
-
-               [CLSCompliant (false)]
-               public static sbyte Abs (sbyte value)
-               {
-                       if (value == SByte.MinValue)
-                               throw new OverflowException (Locale.GetText ("Value is too small."));
-                       return (sbyte)((value < 0)? -value: value);
-               }
-
-               public static short Abs (short value)
-               {
-                       if (value == Int16.MinValue)
-                               throw new OverflowException (Locale.GetText ("Value is too small."));
-                       return (short)((value < 0)? -value: value);
-               }
-
-               public static decimal Ceiling (decimal d)
-               {
-                       decimal result = Floor(d);
-                       if (result != d) {
-                               result++;
-                       }
-                       return result;
-               }
-
-               public static double Ceiling (double a)
-               {
-                       double result = Floor(a);
-                       if (result != a) {
-                               result++;
-                       }
-                       return result;
-               }
-
-               // The following methods are defined in ECMA specs but they are
-               // not implemented in MS.NET. However, they are in MS.NET 1.1
-
-               public static long BigMul (int a, int b)
-               {
-                       return ((long)a * (long)b);
-               }
-
-               public static int DivRem (int a, int b, out int result)
-               {
-                       result = (a % b);
-                       return (int)(a / b);
-               }
-
-               public static long DivRem (long a, long b, out long result)
-               {
-                       result = (a % b);
-                       return (long)(a / b);
-               }
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Floor (double d);
-
-               public static double IEEERemainder (double x, double y)
-               {
-                       double r;
-                       if (y == 0)
-                               return Double.NaN;
-                       r = x - (y * Math.Round(x/y));
-                       if (r != 0)
-                               return r;
-                       /* Int64BitsToDouble is not endian-aware, but that is fine here */
-                       return (x > 0) ? 0: (BitConverter.Int64BitsToDouble (Int64.MinValue));
-               }
-
-               public static double Log (double a, double newBase)
-               {
-                       if (newBase == 1.0)
-                               return Double.NaN;
-                       double result = Log(a) / Log(newBase);
-                       return (result == -0)? 0: result;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static byte Max (byte val1, byte val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static decimal Max (decimal val1, decimal val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static double Max (double val1, double val2)
-               {
-                       if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
-                               return Double.NaN;
-                       }
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static float Max (float val1, float val2)
-               {
-                       if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
-                               return Single.NaN;
-                       }
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static int Max (int val1, int val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static long Max (long val1, long val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static sbyte Max (sbyte val1, sbyte val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static short Max (short val1, short val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static uint Max (uint val1, uint val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static ulong Max (ulong val1, ulong val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static ushort Max (ushort val1, ushort val2)
-               {
-                       return (val1 > val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static byte Min (byte val1, byte val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static decimal Min (decimal val1, decimal val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static double Min (double val1, double val2)
-               {
-                       if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
-                               return Double.NaN;
-                       }
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static float Min (float val1, float val2)
-               {
-                       if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
-                               return Single.NaN;
-                       }
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static int Min (int val1, int val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static long Min (long val1, long val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static sbyte Min (sbyte val1, sbyte val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static short Min (short val1, short val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static uint Min (uint val1, uint val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static ulong Min (ulong val1, ulong val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [CLSCompliant (false)]
-               public static ushort Min (ushort val1, ushort val2)
-               {
-                       return (val1 < val2)? val1: val2;
-               }
-
-               public static decimal Round (decimal d)
-               {
-                       // Just call Decimal.Round(d, 0); when it rounds well.
-                       decimal int_part = Decimal.Floor(d);
-                       decimal dec_part = d - int_part;
-                       if (((dec_part == 0.5M) &&
-                               ((2.0M * ((int_part / 2.0M) -
-                               Decimal.Floor(int_part / 2.0M))) != 0.0M)) ||
-                               (dec_part > 0.5M)) {
-                               int_part++;
-                       }
-                       return int_part;
-               }
-
-               public static decimal Round (decimal d, int decimals)
-               {
-                       return Decimal.Round (d, decimals);
-               }
-
-               public static decimal Round (decimal d, MidpointRounding mode)
-               {
-                       if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
-                               throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
-
-                       if (mode == MidpointRounding.ToEven)
-                               return Round (d);
-                       else
-                               return RoundAwayFromZero (d);
-               }
-
-               static decimal RoundAwayFromZero (decimal d)
-               {
-                       decimal int_part = Decimal.Floor(d);
-                       decimal dec_part = d - int_part;
-                       if (int_part >= 0 && dec_part >= 0.5M)
-                               int_part++;
-                       else if (int_part < 0 && dec_part > 0.5M)
-                               int_part++;
-                       return int_part;
-               }
-
-               public static decimal Round (decimal d, int decimals, MidpointRounding mode)
-               {
-                       return Decimal.Round (d, decimals, mode);
-               }
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Round (double a);
-
-               public static double Round (double value, int digits)
-               {
-                       if (digits < 0 || digits > 15)
-                               throw new ArgumentOutOfRangeException (Locale.GetText ("Value is too small or too big."));
-                       if (digits == 0)
-                               return Round (value);
-
-                       return Round2(value, digits, false);
-               }
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private extern static double Round2 (double value, int digits, bool away_from_zero);
-
-
-               public static double Round (double value, MidpointRounding mode)
-               {
-                       if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
-                               throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
-
-                       if (mode == MidpointRounding.ToEven)
-                               return Round (value);
-                       if (value > 0)
-                               return Floor (value + 0.5);
-                       else
-                               return Ceiling (value - 0.5);
-               }
-
-               public static double Round (double value, int digits, MidpointRounding mode)
-               {
-                       if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
-                               throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
-                       if (digits == 0)
-                               return Round (value, mode);
-
-                       if (mode == MidpointRounding.ToEven)
-                               return Round (value, digits);
-                       else
-                               return Round2 (value, digits, true);
-               }
-               
-               public static double Truncate (double d)
-               {
-                       if (d > 0D)
-                               return Floor (d);
-                       else if (d < 0D)
-                               return Ceiling (d);
-                       else
-                               return d;
-               }
-
-               public static decimal Truncate (decimal d)
-               {
-                       return Decimal.Truncate (d);
-               }
-
-               public static decimal Floor (Decimal d)
-               {
-                       return Decimal.Floor (d);
-               }
-
-               public static int Sign (decimal value)
-               {
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               public static int Sign (double value)
-               {
-                       if (Double.IsNaN (value))
-                               throw new ArithmeticException ("NAN");
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               public static int Sign (float value)
-               {
-                       if (Single.IsNaN (value))
-                               throw new ArithmeticException ("NAN");
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               public static int Sign (int value)
-               {
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               public static int Sign (long value)
-               {
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               [CLSCompliant (false)]
-               public static int Sign (sbyte value)
-               {
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               public static int Sign (short value)
-               {
-                       if (value > 0) return 1;
-                       return (value == 0)? 0: -1;
-               }
-
-               // internal calls
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Sin (double a);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Cos (double d);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Tan (double a);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Sinh (double value);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Cosh (double value);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Tanh (double value);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Acos (double d);
-               
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Asin (double d);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Atan (double d);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Atan2 (double y, double x);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Exp (double d);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Log (double d);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Log10 (double d);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static double Pow (double x, double y);
-
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public extern static double Sqrt (double d);
-       }
-}
index 8c661389b351873fafe0da6464dda2077e69bc94..45475e910b5caebc26b28d8ce92b16e5b026b2ef 100644 (file)
@@ -266,7 +266,7 @@ namespace System {
                        return timeZoneInfo;
                }
 
-               static void GetSystemTimeZones (List<TimeZoneInfo> systemTimeZones)
+               static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
                {
                        foreach (string id in AndroidTimeZones.GetAvailableIds ()) {
                                var tz = AndroidTimeZones.GetTimeZone (id, id);
index 3db0c0ab646d33141b3a373c49c7f557b43817d7..ba161b3f2e2f37856954f3f1be325ab10f286ee3 100644 (file)
@@ -58,7 +58,7 @@ namespace System {
                        }
                }
 
-               static void GetSystemTimeZones (List<TimeZoneInfo> systemTimeZones)
+               static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
                {
                        foreach (string name in GetMonoTouchNames ()) {
                                using (Stream stream = GetMonoTouchData (name, false)) {
index 3f0a069fa06f955fe23655bbd3e22ec0f21559b5..d3fc6ff2c6615a6614d78497aab908a3d13d5bd6 100644 (file)
@@ -33,6 +33,7 @@ using System.Threading;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
 using System.Text;
 using System.Globalization;
 using System.IO;
@@ -89,6 +90,58 @@ namespace System
                */
                private List<KeyValuePair<DateTime, TimeType>> transitions;
 
+               private static bool libcNotFound;
+
+               [DllImport ("libc")]
+               private static extern int readlink (string path, byte[] buffer, int buflen);
+
+               private static string readlink (string path)
+               {
+                       if (libcNotFound)
+                               return null;
+
+                       byte[] buf = new byte [512];
+                       int ret;
+
+                       try {
+                               ret = readlink (path, buf, buf.Length);
+                       } catch (DllNotFoundException e) {
+                               libcNotFound = true;
+                               return null;
+                       }
+
+                       if (ret == -1) return null;
+                       char[] cbuf = new char [512];
+                       int chars = System.Text.Encoding.Default.GetChars (buf, 0, ret, cbuf, 0);
+                       return new String (cbuf, 0, chars);
+               }
+
+               private static bool TryGetNameFromPath (string path, out string name)
+               {
+                       name = null;
+                       var linkPath = readlink (path);
+                       if (linkPath != null)
+                               path = linkPath;
+
+                       path = Path.GetFullPath (path);
+
+                       if (string.IsNullOrEmpty (TimeZoneDirectory))
+                               return false;
+
+                       var baseDir = TimeZoneDirectory;
+                       if (baseDir [baseDir.Length-1] != Path.DirectorySeparatorChar)
+                               baseDir += Path.DirectorySeparatorChar;
+
+                       if (!path.StartsWith (baseDir, StringComparison.InvariantCulture))
+                               return false;
+
+                       name = path.Substring (baseDir.Length);
+                       if (name == "localtime")
+                               name = "Local";
+
+                       return true;
+               }
+
 #if !MOBILE || MOBILE_STATIC
                static TimeZoneInfo CreateLocal ()
                {
@@ -114,15 +167,22 @@ namespace System
                                }
                        }
 
-                       try {
-                               return FindSystemTimeZoneByFileName ("Local", "/etc/localtime");        
-                       } catch (TimeZoneNotFoundException) {
+                       var tzFilePaths = new string [] {
+                               "/etc/localtime",
+                               Path.Combine (TimeZoneDirectory, "localtime")};
+
+                       foreach (var tzFilePath in tzFilePaths) {
                                try {
-                                       return FindSystemTimeZoneByFileName ("Local", Path.Combine (TimeZoneDirectory, "localtime"));   
+                                       string tzName = null;
+                                       if (!TryGetNameFromPath (tzFilePath, out tzName))
+                                               tzName = "Local";
+                                       return FindSystemTimeZoneByFileName (tzName, tzFilePath);
                                } catch (TimeZoneNotFoundException) {
-                                       return Utc;
+                                       continue;
                                }
                        }
+
+                       return Utc;
                }
 
                static TimeZoneInfo FindSystemTimeZoneByIdCore (string id)
@@ -135,7 +195,7 @@ namespace System
 #endif
                }
 
-               static void GetSystemTimeZones (List<TimeZoneInfo> systemTimeZones)
+               static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
                {
 #if !MOBILE_STATIC
                        if (TimeZoneKey != null) {
@@ -651,7 +711,7 @@ namespace System
                {
                        if (systemTimeZones == null) {
                                var tz = new List<TimeZoneInfo> ();
-                               GetSystemTimeZones (tz);
+                               GetSystemTimeZonesCore (tz);
                                Interlocked.CompareExchange (ref systemTimeZones, new ReadOnlyCollection<TimeZoneInfo> (tz), null);
                        }
 
index 459974cdee4510253d0c38f84162660fd6ca688e..66eb27ed32407833e14b69f9fc6cb357b4f3d7ab 100644 (file)
@@ -1034,7 +1034,6 @@ namespace MonoTests.System.IO.IsolatedStorageTest {
                                isf.MoveFile ("  ", "file-new-new");
                                Assert.Fail ("#Exc2");
                        } catch (ArgumentException e) {
-                               Console.WriteLine (e);
                        }
 
                        try {
index bdeae0ba3aa6a2db36a900e8832fc1c7854456e4..dca54d652affc4eb71ca1c2c335bc4b7ffdfe327 100644 (file)
@@ -16,6 +16,7 @@ using System.IO;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading;
+using Microsoft.Win32.SafeHandles;
 
 namespace MonoTests.System.IO
 {
@@ -1678,6 +1679,17 @@ namespace MonoTests.System.IO
                                DeleteFile (path);
                        }
                }
+
+               [Test]
+               public void Ctor_InvalidSafeHandle ()
+               {
+                       var sf = new SafeFileHandle (IntPtr.Zero, true);
+                       try {
+                               new FileStream (sf, FileAccess.ReadWrite);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException) {
+                       }
+               }
 #endif
        }
 }
index 949c7365b9a5e9084b4a57ecede9343db892ffe9..c9a00481185d6374280d065700948e97c184f999 100644 (file)
@@ -12,6 +12,8 @@ using System.Reflection;
 using System.Reflection.Emit;
 using System.Runtime.InteropServices;
 using System.Text;
+using System.Diagnostics;
+using System.Runtime.ExceptionServices;
 
 using NUnit.Framework;
 
@@ -477,6 +479,104 @@ namespace MonoTests.System.Reflection.Emit
                        public string Name;
                }
 
+               class ExceptionHandling_Test_Support
+               {
+                       public static Exception Caught;
+                       public static string CaughtStackTrace;
+
+                       public static void ThrowMe ()
+                       {
+                               Caught = null;
+                               CaughtStackTrace = null;
+                               throw new Exception("test");
+                       }
+
+                       public static void Handler (Exception e)
+                       {
+                               Caught = e;
+                               CaughtStackTrace = e.StackTrace.ToString ();
+                       }
+               }
+
+               [Test]
+               public void ExceptionHandling ()
+               {
+                       var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
+                       var ig = method.GetILGenerator ();
+
+                       ig.BeginExceptionBlock();
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("ThrowMe"));
+
+                       ig.BeginCatchBlock(typeof(Exception));
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("Handler"));
+                       ig.EndExceptionBlock();
+
+                       ig.Emit(OpCodes.Ret);
+
+                       var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
+                       invoke (456324);
+
+                       Assert.IsNotNull (ExceptionHandling_Test_Support.Caught, "#1");
+                       Assert.AreEqual (2, ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None).Length, "#2");
+
+                       var st = new StackTrace (ExceptionHandling_Test_Support.Caught, 0, true);
+
+                       // Caught stack trace when dynamic method is gone
+                       Assert.AreEqual (ExceptionHandling_Test_Support.CaughtStackTrace, st.ToString (), "#3");
+
+                       // Catch handler stack trace inside dynamic method match
+                       Assert.AreEqual (ExceptionHandling_Test_Support.Caught.StackTrace, st.ToString (), "#4");
+               }
+
+               class ExceptionHandlingWithExceptionDispatchInfo_Test_Support
+               {
+                       public static Exception Caught;
+                       public static string CaughtStackTrace;
+
+                       public static void ThrowMe ()
+                       {
+                               Caught = null;
+                               CaughtStackTrace = null;
+
+                               Exception e;
+                               try {
+                                       throw new Exception("test");
+                               } catch (Exception e2) {
+                                       e = e2;
+                               }
+
+                               var edi = ExceptionDispatchInfo.Capture(e);
+
+                               edi.Throw();
+                       }
+
+                       public static void Handler (Exception e)
+                       {
+                               var split = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+                               Assert.AreEqual (5, split.Length, "#1");
+                               Assert.IsTrue (split [1].Contains ("---"), "#2");
+                       }
+               }
+
+               [Test]
+               public void ExceptionHandlingWithExceptionDispatchInfo ()
+               {
+                       var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
+                       var ig = method.GetILGenerator ();
+
+                       ig.BeginExceptionBlock();
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("ThrowMe"));
+
+                       ig.BeginCatchBlock(typeof(Exception));
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("Handler"));
+                       ig.EndExceptionBlock();
+
+                       ig.Emit(OpCodes.Ret);
+
+                       var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
+                       invoke (444);
+               }
+
 #if !MONODROID
                // RUNTIME: crash
                [Test]
index 576b7380707efa5f84e1d5a0cbf06495c71822c7..4d8f1bf0ddace880834887a756e0b5f4aea2b91a 100644 (file)
@@ -1807,6 +1807,28 @@ public class AssemblyNameTest {
                }
        }
 
+       [Test] // ctor (String)
+       public void Constructor1_Quoted ()
+       {
+               AssemblyName an;
+
+               an = new AssemblyName ("'System', Version=\"10.0.0.0\", Culture='Neutral', PublicKeyToken='b67a5c561934e089', Retargetable='Yes', ProcessorArchitecture='AMD64'");
+               Assert.AreEqual ("System, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b67a5c561934e089, Retargetable=Yes", an.ToString ());
+               Assert.AreEqual (ProcessorArchitecture.Amd64, an.ProcessorArchitecture, "Amd64");
+       }
+
+       [Test] // ctor (String)
+       public void Constructor1_Quoted_Invalid ()
+       {
+               AssemblyName an;
+
+               try {
+                       an = new AssemblyName ("System, Version=\"10.0.0.0'");
+                       Assert.Fail ("#1");
+               } catch (FileLoadException) {
+               }
+       }
+
        [Test (Description="Xamarin bug #99 - whitespaces in key=value")]
        public void WhiteSpaceInKeyValue ()
        {
index 5a1223795b5bf382c0dbabfe8d13d003522e6466..cf4ed9a7eaa2011fe8e93e9409669f9670314a51 100644 (file)
@@ -140,5 +140,14 @@ namespace MonoTests.System.Reflection
                        var ctor = typeof (Gen<>).GetConstructor (Type.EmptyTypes);
                        Assert.IsTrue (ctor.ContainsGenericParameters);
                }
+
+               [Test]
+               public void ConstructorInfoModule ()
+               {
+                       Type type = typeof (Foo);
+                       ConstructorInfo co = type.GetConstructors ()[0];
+
+                       Assert.AreEqual (type.Module, co.Module);
+               }
        }
 }
index 8147e9fe839aebe39d35a3f9004b869c4a2e21a9..311bf0f56a760fa14ac02c97ff349f39eba94fc6 100644 (file)
@@ -114,6 +114,15 @@ namespace MonoTests.System.Reflection
                        } catch (InvalidOperationException) {}                  
                }
 
+               [Test]
+               public void EventInfoModule ()
+               {
+                       Type type = typeof (TestClass);
+                       EventInfo ev = type.GetEvent ("pub");
+
+                       Assert.AreEqual (type.Module, ev.Module);
+               }
+
 #pragma warning disable 67
                public class PrivateEvent
                {
index 33c6fea356002d36fd7aa17208f76213e7aa3fed..3650cadc47f3124e3e96f6489ea309d5d16b24ec 100644 (file)
@@ -400,6 +400,15 @@ namespace MonoTests.System.Reflection
                        //Assert.IsTrue (pi.IsRetval, "#3");
                }
 
+               [Test]
+               public void MethodInfoModule ()
+               {
+                       Type type = typeof (MethodInfoTest);
+                       MethodInfo me = type.GetMethod ("return_parameter_test");
+
+                       Assert.AreEqual (type.Module, me.Module);
+               }
+
                [Test]
                        public void InvokeOnRefOnlyAssembly ()
                {
index 49af23097c821009566f39ac66b60b723b58fe1a..dd38e16b7e52e7588d05cdbb637b9ae47da88b5b 100644 (file)
@@ -48,6 +48,7 @@ namespace MonoTests.System.Reflection
                {
                        Type type = typeof (TestClass);
                        PropertyInfo property = type.GetProperty ("ReadOnlyProperty");
+                       Assert.IsNotNull (property.Module, "#0");
 
                        MethodInfo [] methods = property.GetAccessors (true);
                        Assert.AreEqual (1, methods.Length, "#A1");
@@ -497,8 +498,20 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual (typeof (ClassWithNullableDateTime), siblingProperty.DeclaringType, "#3");
                        Assert.AreEqual (typeof (InheritsFromClassWithNullableDateTime), siblingProperty.ReflectedType, "#4");
                }
-               
-       
+
+               class Super { public long A { get; private set; } }
+
+               class Sub : Super { }
+
+               [Test]
+               public void PrivateSetterFromDerivedType ()
+               {
+                       var prop = typeof (Sub).GetProperty ("A");
+                       Assert.AreEqual (1, prop.GetAccessors (true).Length, "#1");
+                       Assert.IsFalse (prop.CanWrite, "#2");
+                       Assert.IsNull (prop.GetSetMethod (true), "#3");
+               }
+
                public class ClassWithNullableDateTime
                {
                        public DateTime? Property1 { get; set; }
index bef832b90c424aabe9d76f11943edbe7947d6671..9c566b4bafcc7111e311a308657b7f7c0922191c 100644 (file)
@@ -30,6 +30,7 @@ using System;
 using NUnit.Framework;
 using System.Runtime.ExceptionServices;
 using System.Threading.Tasks;
+using System.Diagnostics;
 
 namespace MonoTests.System.Runtime.ExceptionServices
 {
@@ -150,7 +151,25 @@ namespace MonoTests.System.Runtime.ExceptionServices
                                Assert.IsTrue (split [1].Contains ("---"), "#2");
                                Assert.IsTrue (split [4].Contains ("---"), "#3");
                        }
-               }               
+               }
+
+               [Test]
+               public void StackTraceUserCopy ()
+               {
+                       try {
+                               try {
+                                       throw new NotImplementedException ();
+                               } catch (Exception e) {
+                                       var edi = ExceptionDispatchInfo.Capture (e);
+                                       edi.Throw();
+                               }
+                       } catch (Exception ex) {
+                               var st = new StackTrace (ex, true);
+                               var split = st.ToString ().Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+                               Assert.AreEqual (4, split.Length, "#1");
+                               Assert.IsTrue (split [1].Contains ("---"), "#2");
+                       }
+               }
        }
 }
 
index 9bfc1c131eaa41121183797895077b5a4f308e8f..53921d2e13f30f80360c47ddd904bd3b26d20f8b 100644 (file)
@@ -800,15 +800,17 @@ namespace MonoTests.System.Threading
                [Test]
                public void Test_Interrupt ()
                {
+                       ManualResetEvent mre = new ManualResetEvent (false);
                        bool interruptedExceptionThrown = false;
+
                        ThreadPool.QueueUserWorkItem (Test_Interrupt_Worker, Thread.CurrentThread);
 
                        try {
                                try {
-                                       Thread.Sleep (3000);
+                                       mre.WaitOne (3000);
                                } finally {
                                        try {
-                                               Thread.Sleep (0);
+                                               mre.WaitOne (0);
                                        } catch (ThreadInterruptedException) {
                                                Assert.Fail ("ThreadInterruptedException thrown twice");
                                        }
@@ -838,11 +840,12 @@ namespace MonoTests.System.Threading
                [Category ("NotDotNet")] // it crashes nunit.
                public void Test_InterruptCurrentThread ()
                {
+                       ManualResetEvent mre = new ManualResetEvent (false);
                        bool interruptedExceptionThrown = false;
 
                        Thread.CurrentThread.Interrupt ();
                        try {
-                               Thread.Sleep (0);
+                               mre.WaitOne (0);
                                Assert.Fail ();
                        } catch (ThreadInterruptedException) {
                        }
index 355b3960b01c10e864abe021e2e19faa9d2d5c77..537604ec2b73a8ea6bd62446e47732f0f48d8b20 100644 (file)
@@ -405,7 +405,7 @@ namespace MonoTests.System
                public void TestIEEERemainder ()
                {
                        double a = Math.IEEERemainder (y, x);
-                       double b = 0.0050000000000007816;
+                       double b = 0.0050000000000010592;
 
                        Assert.IsTrue ((Math.Abs (a - b) <= double_epsilon), a.ToString ("G99")
                                + " != " + b.ToString ("G99"));
@@ -456,7 +456,8 @@ namespace MonoTests.System
                        // MS docs say this should be PositiveInfinity
                        Assert.IsTrue (Math.Log (0, y) == double.NegativeInfinity);
                        Assert.IsTrue (Math.Log (double.PositiveInfinity, y) == double.PositiveInfinity);
-                       Assert.IsTrue (Math.Log (x, double.PositiveInfinity) == 0);
+
+                       Assert.IsTrue (Double.IsNaN (Math.Log (x, double.PositiveInfinity)));
                }
 
                [Test]
@@ -488,82 +489,109 @@ namespace MonoTests.System
                        //
                        // when using double_epsilon. Precision differs between different ARM CPUs, so we
                        // will just use a more conservative value
-                       precision = 0.000001;
+                       precision = double_epsilon * 10;
 #else
                        precision = double_epsilon;
 #endif
-                       try {
-                               double a = Math.Pow (y, x);
-                               double b = 1.363609446060212;
-
-                               Assert.IsTrue ((Math.Abs (a - b) <= precision), a.ToString ("G99") + " != " + b.ToString ("G99"));
-                               iTest++;
-                               Assert.IsTrue (double.IsNaN (Math.Pow (y, double.NaN)));
-                               iTest++;
-                               Assert.IsTrue (double.IsNaN (Math.Pow (double.NaN, x)));
-                               iTest++;
-                               Assert.IsTrue (double.IsNegativeInfinity (Math.Pow (double.NegativeInfinity, 1)),
-                                       "Math.Pow(double.NegativeInfinity, 1) should be NegativeInfinity");
-                               iTest++;
-                               Assert.IsTrue (double.IsPositiveInfinity (Math.Pow (double.NegativeInfinity, 2)),
-                                       "Math.Pow(double.NegativeInfinity, 2) should be PositiveInfinity");
 
-                               // MS docs say this should be 0
-                               iTest++;
-                               Assert.IsTrue (double.IsNaN (Math.Pow (1, double.NegativeInfinity)));
-                               iTest++;
-                               Assert.AreEqual ((double) 0, Math.Pow (double.PositiveInfinity, double.NegativeInfinity),
-                                       "Math.Pow(double.PositiveInfinity, double.NegativeInfinity)");
-                               iTest++;
-                               Assert.IsTrue (double.IsPositiveInfinity (Math.Pow (double.PositiveInfinity, 1)),
-                                       "Math.Pow(double.PositiveInfinity, 1) should be PositiveInfinity");
-
-                               // MS docs say this should be PositiveInfinity
-                               iTest++;
-                               Assert.IsTrue (double.IsNaN (Math.Pow (1, double.PositiveInfinity)),
-                                       "Math.Pow(1, double.PositiveInfinity) should be NaN");
-
-                               iTest++;
-                               Assert.IsTrue (Double.IsNaN (Math.Pow (1, Double.NaN)),
-                                       "Math.Pow(1, NaN) should be NaN");
-                               iTest++;
-                               Assert.IsTrue (Double.IsNaN (Math.Pow (Double.NaN, 0)),
-                                       "Math.Pow(NaN, 0) should be NaN");
-                               iTest++;
-                               Assert.IsTrue (1.0 == Math.Pow (-1, Double.MaxValue),
-                                       "Math.Pow(-1, MaxValue) should be 1.0");
-
-                               iTest++;
-                               Assert.IsTrue (1.0 == Math.Pow (-1, Double.MinValue),
-                                       "Math.Pow(-1, MinValue) should be 1.0");
-
-                               iTest++;
-                               Assert.IsTrue (Double.IsPositiveInfinity (Math.Pow (Double.MinValue,
-                                       Double.MaxValue)), "Math.Pow(MinValue, MaxValue) should be +Infinity");
-
-                               iTest++;
-                               Assert.IsTrue (0.0 == Math.Pow (Double.MinValue, Double.MinValue),
-                                       "Math.Pow(MinValue, MinValue) should be 0.0");
-
-                               //
-                               // The following bugs were present because we tried to outsmart the C Pow:
-                               //
-                               double infinity = Double.PositiveInfinity;
-                               Assert.IsTrue (Math.Pow (0.5, infinity) == 0.0,
-                                       "Math.Pow(0.5, Infinity) == 0.0");
-                               Assert.IsTrue (Math.Pow (0.5, -infinity) == infinity,
-                                       "Math.Pow(0.5, -Infinity) == Infinity");
-                               Assert.IsTrue (Math.Pow (2, infinity) == infinity,
-                                       "Math.Pow(2, Infinity) == Infinity");
-                               Assert.IsTrue (Math.Pow (2, -infinity) == 0.0,
-                                       "Math.Pow(2, -Infinity) == 0");
-                               Assert.IsTrue (Math.Pow (infinity, 0) == 1.0,
-                                       "Math.Pow(Infinity, 0) == 1.0");
-                               Assert.IsTrue (Math.Pow (-infinity, 0) == 1.0,
-                                       "Math.Pow(-Infinity, 0) == 1.0");
-                       } catch (Exception e) {
-                               Assert.Fail ("Unexpected exception at iTest=" + iTest + ". e=" + e);
-                       }
+                       /* documentation cases : https://msdn.microsoft.com/en-us/library/system.math.pow%28v=vs.110%29.aspx */
+
+                       /* x or y = NaN -> NaN */
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN,              double.NaN)), "#1");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN, double.NegativeInfinity)), "#2");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN,                      -2)), "#2");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN,                      -1)), "#3");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN,                       0)), "#4");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN,                       1)), "#5");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN,                       2)), "#6");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (             double.NaN, double.PositiveInfinity)), "#7");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (double.NegativeInfinity,              double.NaN)), "#8");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (                     -2,              double.NaN)), "#9");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (                     -1,              double.NaN)), "#10");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (                      0,              double.NaN)), "#11");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (                      1,              double.NaN)), "#12");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (                      2,              double.NaN)), "#13");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (double.PositiveInfinity,              double.NaN)), "#14");
+
+                       /* x = Any value except NaN; y = 0 -> 1 */
+                       Assert.AreEqual ((double) 1, Math.Pow (2, 0), "#15");
+
+                       /* x = NegativeInfinity; y < 0 -> 0 */
+                       Assert.AreEqual ((double) 0, Math.Pow (double.NegativeInfinity, -2), "#16");
+
+                       /* x = NegativeInfinity; y is a positive odd integer -> NegativeInfinity */
+                       Assert.AreEqual (double.NegativeInfinity, Math.Pow (double.NegativeInfinity, 3), "#17");
+
+                       /* x = NegativeInfinity; y is positive but not an odd integer -> PositiveInfinity */
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.NegativeInfinity, 2), "#18");
+
+                       /* x < 0 but not NegativeInfinity; y is not an integer, NegativeInfinity, or PositiveInfinity -> NaN */
+                       Assert.IsTrue (double.IsNaN (Math.Pow (-1, 2.5)), "#19");
+
+                       /* x = -1; y = NegativeInfinity or PositiveInfinity -> NaN */
+                       Assert.IsTrue (double.IsNaN (Math.Pow (-1, double.PositiveInfinity)), "#20");
+                       Assert.IsTrue (double.IsNaN (Math.Pow (-1, double.NegativeInfinity)), "#21");
+
+                       /* -1 < x < 1; y = NegativeInfinity -> PositiveInfinity */
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (-0.5, double.NegativeInfinity), "#22");
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (+0.5, double.NegativeInfinity), "#23");
+
+                       /* -1 < x < 1; y = PositiveInfinity -> 0 */
+                       Assert.AreEqual ((double) 0, Math.Pow (-0.5, double.PositiveInfinity), "#24");
+                       Assert.AreEqual ((double) 0, Math.Pow (+0.5, double.PositiveInfinity), "#25");
+
+                       /* x < -1 or x > 1; y = NegativeInfinity -> 0 */
+                       Assert.AreEqual ((double) 0, Math.Pow (-2, double.NegativeInfinity), "#26");
+                       Assert.AreEqual ((double) 0, Math.Pow (+2, double.NegativeInfinity), "#27");
+
+                       /* x < -1 or x > 1; y = PositiveInfinity -> PositiveInfinity */
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (-2, double.PositiveInfinity), "#28");
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (+2, double.PositiveInfinity), "#29");
+
+                       /* x = 0; y < 0 -> PositiveInfinity */
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (0, -2), "#30");
+
+                       /* x = 0; y > 0 -> PositiveInfinity */
+                       Assert.AreEqual ((double) 0, Math.Pow (0, +2), "#31");
+
+                       /* x = 1; y is any value except NaN -> 1 */
+                       Assert.AreEqual ((double) 1, Math.Pow (1, double.NegativeInfinity), "#32");
+                       Assert.AreEqual ((double) 1, Math.Pow (1,                      -2), "#33");
+                       Assert.AreEqual ((double) 1, Math.Pow (1,                       0), "#34");
+                       Assert.AreEqual ((double) 1, Math.Pow (1,                      +2), "#35");
+                       Assert.AreEqual ((double) 1, Math.Pow (1, double.PositiveInfinity), "#36");
+
+                       /* x = PositiveInfinity; y < 0 -> 0 */
+                       Assert.AreEqual ((double) 0, Math.Pow (double.PositiveInfinity, -1), "#37");
+                       Assert.AreEqual ((double) 0, Math.Pow (double.PositiveInfinity, -2), "#38");
+
+                       /* x = PositiveInfinity; y > 0 -> PositiveInfinity */
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.PositiveInfinity, 1), "#39");
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.PositiveInfinity, 2), "#40");
+
+                       /* other cases */
+
+                       double a = Math.Pow (y, x);
+                       double b = 1.363609446060212;
+
+                       Assert.IsTrue (Math.Abs (a - b) <= precision, "#41 " + a.ToString ("G99") + " != " + b.ToString ("G99") + " +/- " + precision.ToString ("G99"));
+                       Assert.AreEqual (double.NegativeInfinity, Math.Pow (double.NegativeInfinity, 1), "#42");
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.NegativeInfinity, 2), "#43");
+
+                       Assert.AreEqual (Math.Pow (double.PositiveInfinity, double.NegativeInfinity), (double) 0, "#44");
+
+                       Assert.AreEqual ((double) 1, Math.Pow (-1, Double.MaxValue), "#45");
+                       Assert.AreEqual ((double) 1, Math.Pow (-1, Double.MinValue), "#46");
+                       Assert.AreEqual ((double) 0, Math.Pow (Double.MinValue, Double.MinValue), "#47");
+                       Assert.AreEqual (double.PositiveInfinity, Math.Pow (Double.MinValue, Double.MaxValue), "#48");
+
+                       double infinity = double.PositiveInfinity;
+                       Assert.AreEqual ((double) 0, Math.Pow (      0.5,  infinity), "#49");
+                       Assert.AreEqual (  infinity, Math.Pow (      0.5, -infinity), "#50");
+                       Assert.AreEqual (  infinity, Math.Pow (        2,  infinity), "#51");
+                       Assert.AreEqual ((double) 0, Math.Pow (        2, -infinity), "#52");
+                       Assert.AreEqual ((double) 1, Math.Pow ( infinity,         0), "#53");
+                       Assert.AreEqual ((double) 1, Math.Pow (-infinity,         0), "#54");
                }
 
                [Test]
index 003cea8ddfe9d5348b3e2a36ebf1f543b3f6c2dc..8648e22df7fb5c482166a760f4c31af2c97134bb 100644 (file)
@@ -28,6 +28,7 @@
 
 using System;
 using System.IO;
+using System.Runtime.InteropServices;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.Collections;
 using System.Reflection;
@@ -50,6 +51,26 @@ namespace MonoTests.System
                                Assert.IsNotNull (local);
                                Assert.IsTrue (true);
                        }
+
+                       [DllImport ("libc")]
+                       private static extern int readlink (string path, byte[] buffer, int buflen);
+
+                       [Test] // Covers #24958
+                       public void LocalId ()
+                       {
+                               byte[] buf = new byte [512];
+
+                               var path = "/etc/localtime";
+                               try {
+                                       var ret = readlink (path, buf, buf.Length);
+                                       if (ret == -1)
+                                               return; // path is not a symbolic link, nothing to test
+                               } catch (DllNotFoundException e) {
+                                       return;
+                               }
+
+                               Assert.IsTrue (TimeZoneInfo.Local.Id != "Local", "Local timezone id should not be \"Local\"");
+                       }
                }
 
                [TestFixture]
@@ -690,6 +711,15 @@ namespace MonoTests.System
                                }
                                Assert.Fail ("Europe/Brussels not found in SystemTZ");
                        }
+
+                       [Test]
+                       public void ReflectionReturnsTheCorrectMethod ()
+                       {
+                               var method = (MethodInfo) typeof (TimeZoneInfo).GetMember ("GetSystemTimeZones", MemberTypes.Method, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)[0];
+
+                               var timeZones = (global::System.Collections.ObjectModel.ReadOnlyCollection<TimeZoneInfo>) method.Invoke (null, null);
+                               Assert.IsTrue (timeZones.Count > 0, "GetSystemTimeZones should not return an empty collection.");
+                       }
                }
                
                [TestFixture]
index 961c6928149290423fac42911fc9ce51e50093b4..7af21cc117bf581d15584d8654d68b906d2ce25c 100644 (file)
@@ -110,7 +110,6 @@ System/IConsoleDriver.cs
 System/IntPtr.cs
 System/KnownTerminals.cs
 System/MarshalByRefObject.cs
-System/Math.cs
 System/MonoAsyncCall.cs
 System/MonoCQItem.cs
 System/MonoCustomAttrs.cs
@@ -1000,6 +999,7 @@ ReferenceSources/SecurityContext.cs
 ../../../external/referencesource/mscorlib/system/iserviceobjectprovider.cs
 ../../../external/referencesource/mscorlib/system/invalidtimezoneexception.cs
 ../../../external/referencesource/mscorlib/system/Lazy.cs
+../../../external/referencesource/mscorlib/system/math.cs
 ../../../external/referencesource/mscorlib/system/memberaccessexception.cs
 ../../../external/referencesource/mscorlib/system/methodaccessexception.cs
 ../../../external/referencesource/mscorlib/system/midpointrounding.cs
index 8f994051c9abc1c6e40e55aca9c53effc5bd5b71..63ddee82bfa286db0e183495ef80d6a93e4d5b90 100644 (file)
@@ -480,6 +480,9 @@ namespace Mono.ILASM {
 %token K_OFF\r
 %token K_FORWARDER\r
 %token K_CHARMAPERROR\r
+%token K_LEGACY\r
+%token K_LIBRARY\r
+%token K_AUTO\r
 \r
 /* end generated */\r
 \r
@@ -3149,9 +3152,9 @@ assembly_all              : assembly_head OPEN_BRACE assembly_decls CLOSE_BRACE
                          }\r
                        ;\r
 \r
-assembly_head          : D_ASSEMBLY asm_attr slashed_name\r
+assembly_head          : D_ASSEMBLY legacylibrary_opt asm_attr slashed_name\r
                           {\r
-                                codegen.SetThisAssembly ((string) $3, (PEAPI.AssemAttr) $2);\r
+                                codegen.SetThisAssembly ((string) $4, (PEAPI.AssemAttr) $3);\r
                                 codegen.CurrentCustomAttrTarget = codegen.ThisAssembly;\r
                                codegen.CurrentDeclSecurityTarget = codegen.ThisAssembly;\r
                           }\r
@@ -3211,19 +3214,19 @@ asm_or_ref_decl         : D_PUBLICKEY ASSIGN bytes_list
 assemblyref_all                : assemblyref_head OPEN_BRACE assemblyref_decls CLOSE_BRACE\r
                        ;\r
 \r
-assemblyref_head       : D_ASSEMBLY K_EXTERN asm_attr slashed_name\r
+assemblyref_head       : D_ASSEMBLY K_EXTERN legacylibrary_opt asm_attr slashed_name\r
                           {\r
                                 System.Reflection.AssemblyName asmb_name = \r
                                        new System.Reflection.AssemblyName ();\r
-                               asmb_name.Name = (string) $4;\r
-                               codegen.BeginAssemblyRef ((string) $4, asmb_name, (PEAPI.AssemAttr) $3);\r
+                               asmb_name.Name = (string) $5;\r
+                               codegen.BeginAssemblyRef ((string) $5, asmb_name, (PEAPI.AssemAttr) $4);\r
                           }\r
-                       | D_ASSEMBLY K_EXTERN asm_attr slashed_name K_AS slashed_name\r
+                       | D_ASSEMBLY K_EXTERN legacylibrary_opt asm_attr slashed_name K_AS slashed_name\r
                           {\r
                                 System.Reflection.AssemblyName asmb_name = \r
                                        new System.Reflection.AssemblyName ();\r
-                               asmb_name.Name = (string) $4;\r
-                               codegen.BeginAssemblyRef ((string) $6, asmb_name, (PEAPI.AssemAttr) $3);\r
+                               asmb_name.Name = (string) $5;\r
+                               codegen.BeginAssemblyRef ((string) $7, asmb_name, (PEAPI.AssemAttr) $4);\r
                           }\r
                        ;\r
 \r
@@ -3258,6 +3261,7 @@ assemblyref_decl  : D_VER int32 COLON int32 COLON int32 COLON int32
                                 if (codegen.CurrentCustomAttrTarget != null)\r
                                         codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1);\r
                           }\r
+            | K_AUTO  /* MS ilasm uses this keyword to lookup the specified assembly in the GAC and embeds its attributes, we just ignore it */\r
                        ;\r
 \r
 exptype_all            : exptype_head OPEN_BRACE exptype_decls CLOSE_BRACE\r
@@ -3424,6 +3428,10 @@ semicolon_opt
                        | SEMICOLON\r
                        ;\r
 \r
+legacylibrary_opt      : /* empty */\r
+                                       | K_LEGACY K_LIBRARY  /* MS ilasm has these keywords for backwards compatibility, we just ignore them */\r
+                                       ;\r
+\r
 %%\r
 \r
 }\r
index 628c9b443670a138ee99946132ff20c06047e1a7..62ab383b6b41134fffc9c73a95d4d1ab29692fdf 100644 (file)
@@ -317,6 +317,9 @@ namespace Mono.ILASM {
                                 keywords ["off"] = new ILToken (Token.K_OFF, "off");\r
                                keywords ["strict"] = new ILToken (Token.K_STRICT, "strict");\r
                                keywords ["forwarder"] = new ILToken (Token.K_FORWARDER, "forwarder");\r
+                                keywords ["legacy"] = new ILToken (Token.K_LEGACY, "legacy");\r
+                                keywords ["library"] = new ILToken (Token.K_LIBRARY, "library");\r
+                                keywords ["auto"] = new ILToken (Token.K_AUTO, "auto");\r
 \r
                                 return keywords;\r
                         }\r
index b4e797bb4862e719636307c75db6f1866a5c178c..558b0a6e07d58a45955705dae2bfb14803da8968 100644 (file)
@@ -884,8 +884,10 @@ namespace Mono.CSharp
                                } else {
                                        Builder.Save (module.Builder.ScopeName, pekind, machine);
                                }
+                       } catch (ArgumentOutOfRangeException) {
+                               Report.Error (16, "Output file `{0}' exceeds the 4GB limit");
                        } catch (Exception e) {
-                               Report.Error (16, "Could not write to file `" + name + "', cause: " + e.Message);
+                               Report.Error (16, "Could not write to file `{0}'. {1}", name, e.Message);
                        }
                        Compiler.TimeReporter.Stop (TimeReporter.TimerType.OutputSave);
 
index 88e523700706480b073713dc308dcdc7b8a31625..fbb21d0096f48e8fa1165057ec3e7d3beab341f6 100644 (file)
@@ -497,7 +497,7 @@ namespace Mono.CSharp
                        }
 
                        foreach (var existing in das) {
-                               if (DefiniteAssignmentBitSet.AreEqual (existing, DefiniteAssignment))
+                               if (DefiniteAssignmentBitSet.IsIncluded (existing, DefiniteAssignment))
                                        return true;
                        }
 
index 518e2c5ab8f6d659c4aa15361c6eb008b935d96f..02f6f3df77494ae11eec7fda3dd1b388fd94fc9b 100644 (file)
@@ -240,6 +240,7 @@ namespace Mono.CSharp
                public bool parsing_catch_when;
 
                int parsing_string_interpolation;
+               int string_interpolation_section;
                Stack<bool> parsing_string_interpolation_quoted;
 
                public bool parsing_interpolation_format;
@@ -411,6 +412,7 @@ namespace Mono.CSharp
                        public int current_token;
                        public object val;
                        public int parsing_string_interpolation;
+                       public int string_interpolation_section;
                        public Stack<bool> parsing_string_interpolation_quoted;
 
                        public Position (Tokenizer t)
@@ -430,9 +432,11 @@ namespace Mono.CSharp
                                        ifstack = new Stack<int> (clone);
                                }
                                parsing_generic_less_than = t.parsing_generic_less_than;
+                               string_interpolation_section = t.string_interpolation_section;
                                current_token = t.current_token;
                                val = t.val;
                                parsing_string_interpolation = t.parsing_string_interpolation;
+                               string_interpolation_section = t.string_interpolation_section;
                                if (t.parsing_string_interpolation_quoted != null && t.parsing_string_interpolation_quoted.Count != 0) {
                                        var clone = t.parsing_string_interpolation_quoted.ToArray ();
                                        Array.Reverse (clone);
@@ -3373,18 +3377,26 @@ namespace Mono.CSharp
 
                                case '{':
                                        val = ltb.Create (current_source, ref_line, col);
+
+                                       if (parsing_string_interpolation > 0)
+                                               ++string_interpolation_section;
+
                                        return Token.OPEN_BRACE;
                                case '}':
                                        if (parsing_string_interpolation > 0) {
-                                               --parsing_string_interpolation;
-                                               bool quoted;
-                                               if (parsing_string_interpolation_quoted != null && parsing_string_interpolation_quoted.Count > 0) {
-                                                       quoted = parsing_string_interpolation_quoted.Pop ();
-                                               } else {
-                                                       quoted = false;
+                                               if (string_interpolation_section == 0) {
+                                                       --parsing_string_interpolation;
+                                                       bool quoted;
+                                                       if (parsing_string_interpolation_quoted != null && parsing_string_interpolation_quoted.Count > 0) {
+                                                               quoted = parsing_string_interpolation_quoted.Pop ();
+                                                       } else {
+                                                               quoted = false;
+                                                       }
+
+                                                       return TokenizeInterpolatedString (quoted);
                                                }
 
-                                               return TokenizeInterpolatedString (quoted);
+                                               --string_interpolation_section;
                                        }
 
                                        val = ltb.Create (current_source, ref_line, col);
index 68e0551bb04fa6d0d620e4421914eed02ffed2d2..ce055dcbc3139d9fc071da68dd444b936968d027 100644 (file)
@@ -1338,8 +1338,14 @@ namespace Mono.CSharp {
                                return null;
 
                        ExpressionStatement es = e as ExpressionStatement;
-                       if (es == null || e is AnonymousMethodBody)
+                       if (es == null || e is AnonymousMethodBody) {
+                               var reduced = e as IReducedExpressionStatement;
+                               if (reduced != null) {
+                                       return EmptyExpressionStatement.Instance;
+                               }
+
                                Error_InvalidExpressionStatement (ec);
+                       }
 
                        //
                        // This is quite expensive warning, try to limit the damage
@@ -1406,6 +1412,10 @@ namespace Mono.CSharp {
                }
        }
 
+       interface IReducedExpressionStatement
+       {
+       }
+
        /// <summary>
        ///   This kind of cast is used to encapsulate the child
        ///   whose type is child.Type into an expression that is
@@ -2213,7 +2223,7 @@ namespace Mono.CSharp {
        //
        public class ReducedExpression : Expression
        {
-               public sealed class ReducedConstantExpression : EmptyConstantCast
+               public class ReducedConstantExpression : EmptyConstantCast
                {
                        readonly Expression orig_expr;
 
@@ -2263,6 +2273,14 @@ namespace Mono.CSharp {
                        }
                }
 
+               sealed class ReducedConstantStatement : ReducedConstantExpression, IReducedExpressionStatement
+               {
+                       public ReducedConstantStatement (Constant expr, Expression origExpr)
+                               : base (expr, origExpr)
+                       {
+                       }
+               }
+
                sealed class ReducedExpressionStatement : ExpressionStatement
                {
                        readonly Expression orig_expr;
@@ -2344,12 +2362,15 @@ namespace Mono.CSharp {
                //
                // Creates fully resolved expression switcher
                //
-               public static Constant Create (Constant expr, Expression original_expr)
+               public static Constant Create (Constant expr, Expression originalExpr)
                {
                        if (expr.eclass == ExprClass.Unresolved)
                                throw new ArgumentException ("Unresolved expression");
 
-                       return new ReducedConstantExpression (expr, original_expr);
+                       if (originalExpr is ExpressionStatement)
+                               return new ReducedConstantStatement (expr, originalExpr);
+
+                       return new ReducedConstantExpression (expr, originalExpr);
                }
 
                public static ExpressionStatement Create (ExpressionStatement s, Expression orig)
index b9189c1f3d6d8aa31ef785065331a78c969c275b..267879c043b75ef8dc40f3df4f150503cd69317c 100644 (file)
@@ -552,7 +552,7 @@ namespace Mono.CSharp
 
                public static DefiniteAssignmentBitSet operator & (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
                {
-                       if (AreEqual (a, b))
+                       if (IsEqual (a, b))
                                return a;
 
                        DefiniteAssignmentBitSet res;
@@ -575,7 +575,7 @@ namespace Mono.CSharp
 
                public static DefiniteAssignmentBitSet operator | (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
                {
-                       if (AreEqual (a, b))
+                       if (IsEqual (a, b))
                                return a;
 
                        DefiniteAssignmentBitSet res;
@@ -678,7 +678,7 @@ namespace Mono.CSharp
                                large_bits[index >> 5] |= (1 << (index & 31));
                }
 
-               public static bool AreEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
+               static bool IsEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
                {
                        if (a.large_bits == null)
                                return (a.bits & ~copy_on_write_flag) == (b.bits & ~copy_on_write_flag);
@@ -690,5 +690,20 @@ namespace Mono.CSharp
 
                        return true;
                }
+
+               public static bool IsIncluded (DefiniteAssignmentBitSet set, DefiniteAssignmentBitSet test)
+               {
+                       var set_bits = set.large_bits;
+                       if (set_bits == null)
+                               return (set.bits & test.bits & ~copy_on_write_flag) == (set.bits & ~copy_on_write_flag);
+
+                       var test_bits = test.large_bits;
+                       for (int i = 0; i < set_bits.Length; ++i) {
+                               if ((set_bits[i] & test_bits[i]) != set_bits[i])
+                                       return false;
+                       }
+
+                       return true;
+               }
        }
 }
index 7868c6a2c9d49b576a63cc69b088fd6e9c722a2d..9c804ceca575e6730e194e54a8bce5735a24cb81 100644 (file)
@@ -217,8 +217,14 @@ namespace Mono.CSharp {
                                        return false;
 
                                statement = Expr as ExpressionStatement;
-                               if (statement == null)
-                                       Expr.Error_InvalidExpressionStatement (ec);
+                               if (statement == null) {
+                                       var reduced = Expr as IReducedExpressionStatement;
+                                       if (reduced != null) {
+                                               statement = EmptyExpressionStatement.Instance;
+                                       } else {
+                                               Expr.Error_InvalidExpressionStatement (ec);
+                                       }
+                               }
 
                                return true;
                        }
index 1d431c4b7580805193a4105b2dc296c7780ffdfa..75bd8b3dd3f4d86efc83ddba5fc179a76bd4082d 100644 (file)
@@ -1222,7 +1222,7 @@ namespace Mono.CSharp {
                                                //
                                                // The return type is actually Task<T> type argument
                                                //
-                                               if (expr.Type == async_type) {
+                                               if (expr.Type == async_type && async_type.TypeArguments [0] != ec.Module.PredefinedTypes.Task.TypeSpec) {
                                                        ec.Report.Error (4016, loc,
                                                                "`{0}': The return expression type of async method must be `{1}' rather than `Task<{1}>'",
                                                                ec.GetSignatureForError (), async_type.TypeArguments[0].GetSignatureForError ());
diff --git a/mcs/tests/gtest-633.cs b/mcs/tests/gtest-633.cs
new file mode 100644 (file)
index 0000000..32882ba
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+
+struct BB
+{}
+
+public class X
+{
+       public static void Main ()
+       {
+               // Reduced expression statements
+               
+               new BB? ();
+               new float();
+
+               Action a = () => new float();
+               a ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-async-68.cs b/mcs/tests/test-async-68.cs
new file mode 100644 (file)
index 0000000..f101c94
--- /dev/null
@@ -0,0 +1,22 @@
+using System.Threading.Tasks;
+
+class X
+{
+       public async Task ReturnsTaskAsync (Task task)
+       {
+               await task;
+       }
+
+       public async Task<Task> ReturnsTaskOfTaskAsync ()
+       {
+               var t1 = Task.FromResult (ReturnsTaskAsync (null));
+               await t1;
+               Task<Task> t2 = Task.FromResult (ReturnsTaskAsync (null));
+               return t2;
+       }
+
+       public static void Main ()
+       {
+               new X ().ReturnsTaskOfTaskAsync ().Wait ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-interpolation-08.cs b/mcs/tests/test-interpolation-08.cs
new file mode 100644 (file)
index 0000000..f617c52
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+
+public class Program
+{
+       public static int Main ()
+       {
+               var x = $@"({
+                               new Dictionary<int, object> {
+                                       { 1, "bbb" }
+                               }.Count
+                               });";
+
+               if (x != "(1);")
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file
index 55d0bf8f5a7962c38f2304fceb1edd8a6f144061..47cfe2ca4691486b451b208e33ce53565de8a80e 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-633.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>38</size>
+      </method>
+      <method name="Void &lt;Main&gt;m__0()" attrs="145">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anontype-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="150">
       </method>
     </type>
   </test>
+  <test name="test-async-68.cs">
+    <type name="X">
+      <method name="System.Threading.Tasks.Task ReturnsTaskAsync(System.Threading.Tasks.Task)" attrs="134">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.Threading.Tasks.Task] ReturnsTaskOfTaskAsync()" attrs="134">
+        <size>41</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>17</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;ReturnsTaskAsync&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>157</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;ReturnsTaskOfTaskAsync&gt;c__async1">
+      <method name="Void MoveNext()" attrs="486">
+        <size>217</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-async-69.cs">
     <type name="Test">
       <method name="System.Threading.Tasks.Task`1[System.Int32] YieldValue(Int32)" attrs="145">
       </method>
     </type>
   </test>
+  <test name="test-interpolation-08.cs">
+    <type name="Program">
+      <method name="Int32 Main()" attrs="150">
+        <size>73</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-iter-01.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
index 2dc2bf799d94c473556fc5796cc6f619e2b5e27b..ec5c1f10aabad6e73e5b4e84fa54d1b42b21a954 100755 (executable)
@@ -156,6 +156,13 @@ class MakeBundle {
                                }
                                ctor_func = args [++i];
                                break;
+                       case "--dos2unix":
+                       case "--dos2unix=true":
+                               use_dos2unix = true;
+                               break;
+                       case "--dos2unix=false":
+                               use_dos2unix = false;
+                               break;
                        default:
                                sources.Add (args [i]);
                                break;
@@ -651,6 +658,10 @@ void          mono_register_config_for_assembly (const char* assembly_name, cons
                                   "    -L path             Adds `path' to the search path for assemblies\n" +
                                   "    --nodeps            Turns off automatic dependency embedding (default)\n" +
                                   "    --deps              Turns on automatic dependency embedding\n" +
+                                  "    --dos2unix[=true|false]\n" +
+                                  "                        When no value provided, or when `true` specified\n" +
+                                  "                        `dos2unix` will be invoked to convert paths on Windows.\n" +
+                                  "                        When `--dos2unix=false` used, dos2unix is NEVER used.\n" +
                                   "    --keeptemp          Keeps the temporary files\n" +
                                   "    --config F          Bundle system config file `F'\n" +
                                   "    --config-dir D      Set MONO_CFG_DIR to `D'\n" +
@@ -704,7 +715,6 @@ void          mono_register_config_for_assembly (const char* assembly_name, cons
                        return system (cmdLine);
                }
                
-#if XAMARIN_ANDROID
                // on Windows, we have to pipe the output of a
                // `cmd` interpolation to dos2unix, because the shell does not
                // strip the CRLFs generated by the native pkg-config distributed
@@ -733,7 +743,6 @@ void          mono_register_config_for_assembly (const char* assembly_name, cons
                }
                // and if there is no dos2unix, just run cmd /c.
                if (use_dos2unix == false) {
-#endif
                        Console.WriteLine (cmdLine);
                        ProcessStartInfo dos2unix = new ProcessStartInfo ();
                        dos2unix.UseShellExecute = false;
@@ -744,19 +753,15 @@ void          mono_register_config_for_assembly (const char* assembly_name, cons
                                p.WaitForExit ();
                                return p.ExitCode;
                        }
-#if XAMARIN_ANDROID
                }
-#endif
 
                StringBuilder b = new StringBuilder ();
                int count = 0;
                for (int i = 0; i < cmdLine.Length; i++) {
                        if (cmdLine [i] == '`') {
-#if XAMARIN_ANDROID
                                if (count % 2 != 0) {
                                        b.Append ("|dos2unix");
                                }
-#endif
                                count++;
                        }
                        b.Append (cmdLine [i]);
index 7e14ab8a62fe7e42a917c0be74fd0e5417a5c793..75d04c1e21ce9d23a8dd31e477b1cf9b23bc83c4 100644 (file)
@@ -39,7 +39,9 @@ BUILD_TEST_EXE = @\
        mkdir -p $(OUT_DIR); \
        $(MCS) -debug $(TEST_CS) -out:$(TEST_EXE)
 
-check: all
+check: test-local
+
+test-local: all
        $(BUILD_TEST_EXE)
        @echo "Checking $(PROGRAM) without AOT"
        $(CHECK_DIFF)
index 6fc37c34271a59f7da5163add23b049f802fdfa5..52ecbbb3fb53f719e83c8f14d9518385d0a148fa 100644 (file)
@@ -13,4 +13,4 @@ run-test-local : basic-tests
 
 basic-tests:
        for type in System.Array System.String 'System.Collections.Generic.List`1'; do \
-       echo $$type; $(RUNTIME) $(build_lib) $$type >/dev/null || exit 1; done
\ No newline at end of file
+       echo $$type; MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(build_lib) $$type >/dev/null || exit 1; done
diff --git a/mono/arch/arm/tramp.c b/mono/arch/arm/tramp.c
deleted file mode 100644 (file)
index f736c7a..0000000
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Create trampolines to invoke arbitrary functions.
- * Copyright (c) 2002 Sergey Chaban <serge@wildwestsoftware.com>
- *
- * Contributions by Malte Hildingson
- */
-
-#include "arm-codegen.h"
-#include "arm-dis.h"
-
-#if defined(_WIN32_WCE) || defined (UNDER_CE)
-#      include <windows.h>
-#else
-#include <unistd.h>
-#include <sys/mman.h>
-#endif
-
-#if !defined(PLATFORM_MACOSX)
-#include <errno.h>
-
-#include "mono/metadata/class.h"
-#include "mono/metadata/tabledefs.h"
-#include "mono/interpreter/interp.h"
-#include "mono/metadata/appdomain.h"
-
-
-#if 0
-#      define ARM_DUMP_DISASM 1
-#endif
-
-/* prototypes for private functions (to avoid compiler warnings) */
-void flush_icache (void);
-void* alloc_code_buff (int num_instr);
-
-
-
-/*
- * The resulting function takes the form:
- * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments);
- * NOTE: all args passed in ARM registers (A1-A4),
- *       then copied to R4-R7 (see definitions below).
- */
-
-#define REG_FUNC_ADDR ARMREG_R4
-#define REG_RETVAL    ARMREG_R5
-#define REG_THIS      ARMREG_R6
-#define REG_ARGP      ARMREG_R7
-
-
-#define ARG_SIZE sizeof(stackval)
-
-
-
-
-void flush_icache ()
-{
-#if defined(_WIN32)
-       FlushInstructionCache(GetCurrentProcess(), NULL, 0);
-#else
-# if 0
-       asm ("mov r0, r0");
-       asm ("mov r0, #0");
-       asm ("mcr p15, 0, r0, c7, c7, 0");
-# else
-       /* TODO: use (movnv  pc, rx) method */
-# endif
-#endif
-}
-
-
-void* alloc_code_buff (int num_instr)
-{
-       void* code_buff;
-       int code_size = num_instr * sizeof(arminstr_t);
-
-#if defined(_WIN32) || defined(UNDER_CE)
-       int old_prot = 0;
-
-       code_buff = malloc(code_size);
-       VirtualProtect(code_buff, code_size, PAGE_EXECUTE_READWRITE, &old_prot);
-#else
-       int page_size = sysconf(_SC_PAGESIZE);
-       int new_code_size;
-
-       new_code_size = code_size + page_size - 1;
-       code_buff = malloc(new_code_size);
-       code_buff = (void *) (((int) code_buff + page_size - 1) & ~(page_size - 1));
-
-       if (mprotect(code_buff, code_size, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) {
-               g_critical (G_GNUC_PRETTY_FUNCTION
-                               ": mprotect error: %s", g_strerror (errno));
-       }
-#endif
-
-       return code_buff;
-}
-
-
-/*
- * Refer to ARM Procedure Call Standard (APCS) for more info.
- */
-MonoPIFunc mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
-{
-       MonoType* param;
-       MonoPIFunc code_buff;
-       arminstr_t* p;
-       guint32 code_size, stack_size;
-       guint32 simple_type;
-       int i, hasthis, aregs, regc, stack_offs;
-       int this_loaded;
-       guchar reg_alloc [ARM_NUM_ARG_REGS];
-
-       /* pessimistic estimation for prologue/epilogue size */
-       code_size = 16 + 16;
-       /* push/pop work regs */
-       code_size += 2; 
-       /* call */
-       code_size += 2;
-       /* handle retval */
-       code_size += 2;
-
-       stack_size = 0;
-       hasthis = sig->hasthis ? 1 : 0;
-
-       aregs = ARM_NUM_ARG_REGS - hasthis;
-
-       for (i = 0, regc = aregs; i < sig->param_count; ++i) {
-               param = sig->params [i];
-
-               /* keep track of argument sizes */
-               if (i < ARM_NUM_ARG_REGS) reg_alloc [i] = 0;
-
-               if (param->byref) {
-                       if (regc > 0) {
-                               code_size += 1;
-                               reg_alloc [i] = regc;
-                               --regc;
-                       } else {
-                               code_size += 2;
-                               stack_size += sizeof(gpointer);
-                       }
-               } else {
-                       simple_type = param->type;
-enum_calc_size:
-                       switch (simple_type) {
-                       case MONO_TYPE_BOOLEAN:
-                       case MONO_TYPE_CHAR:
-                       case MONO_TYPE_I1:
-                       case MONO_TYPE_U1:
-                       case MONO_TYPE_I2:
-                       case MONO_TYPE_U2:
-                       case MONO_TYPE_I4:
-                       case MONO_TYPE_U4:
-                       case MONO_TYPE_I:
-                       case MONO_TYPE_U:
-                       case MONO_TYPE_PTR:
-                       case MONO_TYPE_R4:
-                       case MONO_TYPE_SZARRAY:
-                       case MONO_TYPE_CLASS:
-                       case MONO_TYPE_OBJECT:
-                       case MONO_TYPE_STRING:
-                               if (regc > 0) {
-                                       /* register arg */
-                                       code_size += 1;
-                                       reg_alloc [i] = regc;
-                                       --regc;
-                               } else {
-                                       /* stack arg */
-                                       code_size += 2;
-                                       stack_size += 4;
-                               }
-                               break;
-                       case MONO_TYPE_I8:
-                       case MONO_TYPE_U8:
-                       case MONO_TYPE_R8:
-                               /* keep track of argument sizes */
-                               if (regc > 1) {
-                                       /* fits into registers, two LDRs */
-                                       code_size += 2;
-                                       reg_alloc [i] = regc;
-                                       regc -= 2;
-                               } else if (regc > 0) {
-                                       /* first half fits into register, one LDR */
-                                       code_size += 1;
-                                       reg_alloc [i] = regc;
-                                       --regc;
-                                       /* the rest on the stack, LDR/STR */
-                                       code_size += 2;
-                                       stack_size += 4;
-                               } else {
-                                       /* stack arg, 4 instrs - 2x(LDR/STR) */
-                                       code_size += 4;
-                                       stack_size += 2 * 4;
-                               }
-                               break;
-                       case MONO_TYPE_VALUETYPE:
-                               if (param->data.klass->enumtype) {
-                                       simple_type = param->data.klass->enum_basetype->type;
-                                       goto enum_calc_size;
-                               }
-
-                               if (mono_class_value_size(param->data.klass, NULL) != 4) {
-                                       g_error("can only marshal enums, not generic structures (size: %d)", mono_class_value_size(param->data.klass, NULL));
-                               }
-                               if (regc > 0) {
-                                       /* register arg */
-                                       code_size += 1;
-                                       reg_alloc [i] = regc;
-                                       --regc;
-                               } else {
-                                       /* stack arg */
-                                       code_size += 2;
-                                       stack_size += 4;
-                               }
-                               break;
-                       default :
-                               break;
-                       }
-               }
-       }
-
-       code_buff = (MonoPIFunc)alloc_code_buff(code_size);
-       p = (arminstr_t*)code_buff;
-
-       /* prologue */
-       p = arm_emit_lean_prologue(p, stack_size,
-               /* save workset (r4-r7) */
-               (1 << ARMREG_R4) | (1 << ARMREG_R5) | (1 << ARMREG_R6) | (1 << ARMREG_R7));
-
-
-       /* copy args into workset */
-       /* callme - always present */
-       ARM_MOV_REG_REG(p, ARMREG_R4, ARMREG_A1);
-       /* retval */
-       if (sig->ret->byref || string_ctor || (sig->ret->type != MONO_TYPE_VOID)) {
-               ARM_MOV_REG_REG(p, ARMREG_R5, ARMREG_A2);
-       }
-       /* this_obj */
-       if (sig->hasthis) {
-               this_loaded = 0;
-               if (stack_size == 0) {
-                       ARM_MOV_REG_REG(p, ARMREG_A1, ARMREG_A3);
-                       this_loaded = 1;
-               } else {
-                       ARM_MOV_REG_REG(p, ARMREG_R6, ARMREG_A3);
-               }
-       }
-       /* args */
-       if (sig->param_count != 0) {
-               ARM_MOV_REG_REG(p, ARMREG_R7, ARMREG_A4);
-       }
-
-       stack_offs = stack_size;
-
-       /* handle arguments */
-       /* in reverse order so we could use r0 (arg1) for memory transfers */
-       for (i = sig->param_count; --i >= 0;) {
-               param = sig->params [i];
-               if (param->byref) {
-                       if (i < aregs && reg_alloc[i] > 0) {
-                               ARM_LDR_IMM(p, ARMREG_A1 + i, REG_ARGP, i*ARG_SIZE);
-                       } else {
-                               stack_offs -= sizeof(armword_t);
-                               ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE);
-                               ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
-                       }
-               } else {
-                       simple_type = param->type;
-enum_marshal:
-                       switch (simple_type) {
-                       case MONO_TYPE_BOOLEAN:
-                       case MONO_TYPE_CHAR:
-                       case MONO_TYPE_I1:
-                       case MONO_TYPE_U1:
-                       case MONO_TYPE_I2:
-                       case MONO_TYPE_U2:
-                       case MONO_TYPE_I4:
-                       case MONO_TYPE_U4:
-                       case MONO_TYPE_I:
-                       case MONO_TYPE_U:
-                       case MONO_TYPE_PTR:
-                       case MONO_TYPE_R4:
-                       case MONO_TYPE_SZARRAY:
-                       case MONO_TYPE_CLASS:
-                       case MONO_TYPE_OBJECT:
-                       case MONO_TYPE_STRING:
-                               if (i < aregs && reg_alloc [i] > 0) {
-                                       /* pass in register */
-                                       ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]), REG_ARGP, i*ARG_SIZE);
-                               } else {
-                                       stack_offs -= sizeof(armword_t);
-                                       ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE);
-                                       ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
-                               }
-                               break;
-                       case MONO_TYPE_I8:
-                       case MONO_TYPE_U8:
-                       case MONO_TYPE_R8:
-                               if (i < aregs && reg_alloc [i] > 0) {
-                                       if (reg_alloc [i] > 1) {
-                                               /* pass in registers */
-                                               ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]), REG_ARGP, i*ARG_SIZE);
-                                               ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]) + 1, REG_ARGP, i*ARG_SIZE + 4);
-                                       } else {
-                                               stack_offs -= sizeof(armword_t);
-                                               ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE + 4);
-                                               ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
-                                               ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]), REG_ARGP, i*ARG_SIZE);
-                                       }
-                               } else {
-                                       /* two words transferred on the stack */
-                                       stack_offs -= 2*sizeof(armword_t);
-                                       ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE);
-                                       ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
-                                       ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE + 4);
-                                       ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs + 4);
-                               }
-                               break;
-                       case MONO_TYPE_VALUETYPE:
-                               if (param->data.klass->enumtype) {
-                                       /* it's an enum value, proceed based on its base type */
-                                       simple_type = param->data.klass->enum_basetype->type;
-                                       goto enum_marshal;
-                               } else {
-                                       if (i < aregs && reg_alloc[i] > 0) {
-                                               int vtreg = ARMREG_A1 + hasthis +
-                                                               hasthis + (aregs - reg_alloc[i]);
-                                               ARM_LDR_IMM(p, vtreg, REG_ARGP, i * ARG_SIZE);
-                                               ARM_LDR_IMM(p, vtreg, vtreg, 0);
-                                       } else {
-                                               stack_offs -= sizeof(armword_t);
-                                               ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i * ARG_SIZE);
-                                               ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R0, 0);
-                                               ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
-                                       }
-                               }
-                               break;
-
-                       default:
-                               break;
-                       }
-               }
-       }
-
-       if (sig->hasthis && !this_loaded) {
-               /* [this] always passed in A1, regardless of sig->call_convention */
-               ARM_MOV_REG_REG(p, ARMREG_A1, REG_THIS);
-       }
-
-       /* call [func] */
-       ARM_MOV_REG_REG(p, ARMREG_LR, ARMREG_PC);
-       ARM_MOV_REG_REG(p, ARMREG_PC, REG_FUNC_ADDR);
-
-       /* handle retval */
-       if (sig->ret->byref || string_ctor) {
-               ARM_STR_IMM(p, ARMREG_R0, REG_RETVAL, 0);
-       } else {
-               simple_type = sig->ret->type;
-enum_retvalue:
-               switch (simple_type) {
-               case MONO_TYPE_BOOLEAN:
-               case MONO_TYPE_I1:
-               case MONO_TYPE_U1:
-                       ARM_STRB_IMM(p, ARMREG_R0, REG_RETVAL, 0);
-                       break;
-               case MONO_TYPE_CHAR:
-               case MONO_TYPE_I2:
-               case MONO_TYPE_U2:
-                       ARM_STRH_IMM(p, ARMREG_R0, REG_RETVAL, 0);
-                       break;
-               /*
-                * A 32-bit integer and integer-equivalent return value
-                * is returned in R0.
-                * Single-precision floating-point values are returned in R0.
-                */
-               case MONO_TYPE_I:
-               case MONO_TYPE_U:
-               case MONO_TYPE_I4:
-               case MONO_TYPE_U4:
-               case MONO_TYPE_R4:
-               case MONO_TYPE_OBJECT:
-               case MONO_TYPE_CLASS:
-               case MONO_TYPE_ARRAY:
-               case MONO_TYPE_SZARRAY:
-               case MONO_TYPE_STRING:
-                       ARM_STR_IMM(p, ARMREG_R0, REG_RETVAL, 0);
-                       break;
-               /*
-                * A 64-bit integer is returned in R0 and R1.
-                * Double-precision floating-point values are returned in R0 and R1.
-                */
-               case MONO_TYPE_I8:
-               case MONO_TYPE_U8:
-               case MONO_TYPE_R8:
-                       ARM_STR_IMM(p, ARMREG_R0, REG_RETVAL, 0);
-                       ARM_STR_IMM(p, ARMREG_R1, REG_RETVAL, 4);
-                       break;
-               case MONO_TYPE_VALUETYPE:
-                       if (sig->ret->data.klass->enumtype) {
-                               simple_type = sig->ret->data.klass->enum_basetype->type;
-                               goto enum_retvalue;
-                       }
-                       break;
-               case MONO_TYPE_VOID:
-                       break;
-               default:
-                       break;
-               }
-       }
-       
-       p = arm_emit_std_epilogue(p, stack_size,
-               /* restore R4-R7 */
-               (1 << ARMREG_R4) | (1 << ARMREG_R5) | (1 << ARMREG_R6) | (1 << ARMREG_R7));
-
-       flush_icache();
-
-#ifdef ARM_DUMP_DISASM
-       _armdis_decode((arminstr_t*)code_buff, ((guint8*)p) - ((guint8*)code_buff));
-#endif
-
-       return code_buff;
-}
-
-
-
-#define MINV_OFFS(member) G_STRUCT_OFFSET(MonoInvocation, member)
-
-
-
-/*
- * Returns a pointer to a native function that can be used to
- * call the specified method.
- * The function created will receive the arguments according
- * to the call convention specified in the method.
- * This function works by creating a MonoInvocation structure,
- * filling the fields in and calling ves_exec_method on it.
- * Still need to figure out how to handle the exception stuff
- * across the managed/unmanaged boundary.
- */
-void* mono_arch_create_method_pointer (MonoMethod* method)
-{
-       MonoMethodSignature* sig;
-       guchar* p, * p_method, * p_stackval_from_data, * p_exec;
-       void* code_buff;
-       int i, stack_size, arg_pos, arg_add, stackval_pos, offs;
-       int areg, reg_args, shift, pos;
-       MonoJitInfo *ji;
-
-       code_buff = alloc_code_buff(128);
-       p = (guchar*)code_buff;
-
-       sig = method->signature;
-
-       ARM_B(p, 3);
-
-       /* embed magic number followed by method pointer */
-       *p++ = 'M';
-       *p++ = 'o';
-       *p++ = 'n';
-       *p++ = 'o';
-       /* method ptr */
-       *(void**)p = method;
-       p_method = p;
-       p += 4;
-
-       /* call table */
-       *(void**)p = stackval_from_data;
-       p_stackval_from_data = p;
-       p += 4;
-       *(void**)p = ves_exec_method;
-       p_exec = p;
-       p += 4;
-
-       stack_size = sizeof(MonoInvocation) + ARG_SIZE*(sig->param_count + 1) + ARM_NUM_ARG_REGS*2*sizeof(armword_t);
-
-       /* prologue */
-       p = (guchar*)arm_emit_lean_prologue((arminstr_t*)p, stack_size,
-           (1 << ARMREG_R4) |
-           (1 << ARMREG_R5) |
-           (1 << ARMREG_R6) |
-           (1 << ARMREG_R7));
-
-       /* R7 - ptr to stack args */
-       ARM_MOV_REG_REG(p, ARMREG_R7, ARMREG_IP);
-
-       /*
-        * Initialize MonoInvocation fields, first the ones known now.
-        */
-       ARM_MOV_REG_IMM8(p, ARMREG_R4, 0);
-       ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(ex));
-       ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(ex_handler));
-       ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(parent));
-
-       /* Set the method pointer. */
-       ARM_LDR_IMM(p, ARMREG_R4, ARMREG_PC, -(int)(p - p_method + sizeof(arminstr_t)*2));
-       ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(method));
-
-       if (sig->hasthis) {
-               /* [this] in A1 */
-               ARM_STR_IMM(p, ARMREG_A1, ARMREG_SP, MINV_OFFS(obj));
-       } else {
-               /* else set minv.obj to NULL */
-               ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(obj));
-       }
-
-       /* copy args from registers to stack */
-       areg = ARMREG_A1 + sig->hasthis;
-       arg_pos = -(int)(ARM_NUM_ARG_REGS - sig->hasthis) * 2 * sizeof(armword_t);
-       arg_add = 0;
-       for (i = 0; i < sig->param_count; ++i) {
-               if (areg >= ARM_NUM_ARG_REGS) break;
-               ARM_STR_IMM(p, areg, ARMREG_R7, arg_pos);
-               ++areg;
-               if (!sig->params[i]->byref) {
-                       switch (sig->params[i]->type) {
-                       case MONO_TYPE_I8:
-                       case MONO_TYPE_U8:
-                       case MONO_TYPE_R8:
-                               if (areg >= ARM_NUM_ARG_REGS) {
-                                       /* load second half of 64-bit arg */
-                                       ARM_LDR_IMM(p, ARMREG_R4, ARMREG_R7, 0);
-                                       ARM_STR_IMM(p, ARMREG_R4, ARMREG_R7, arg_pos + sizeof(armword_t));
-                                       arg_add = sizeof(armword_t);
-                               } else {
-                                       /* second half is already the register */
-                                       ARM_STR_IMM(p, areg, ARMREG_R7, arg_pos + sizeof(armword_t));
-                                       ++areg;
-                               }
-                               break;
-                       case MONO_TYPE_VALUETYPE:
-                               /* assert */
-                       default:
-                               break;
-                       }
-               }
-               arg_pos += 2 * sizeof(armword_t);
-       }
-       /* number of args passed in registers */
-       reg_args = i;
-
-
-
-       /*
-        * Calc and save stack args ptr,
-        * args follow MonoInvocation struct on the stack.
-        */
-       ARM_ADD_REG_IMM8(p, ARMREG_R1, ARMREG_SP, sizeof(MonoInvocation));
-       ARM_STR_IMM(p, ARMREG_R1, ARMREG_SP, MINV_OFFS(stack_args));
-
-       /* convert method args to stackvals */
-       arg_pos = -(int)(ARM_NUM_ARG_REGS - sig->hasthis) * 2 * sizeof(armword_t);
-       stackval_pos = sizeof(MonoInvocation);
-       for (i = 0; i < sig->param_count; ++i) {
-               if (i < reg_args) {
-                       ARM_SUB_REG_IMM8(p, ARMREG_A3, ARMREG_R7, -arg_pos);
-                       arg_pos += 2 * sizeof(armword_t);
-               } else {
-                       if (arg_pos < 0) arg_pos = 0;
-                       pos = arg_pos + arg_add;
-                       if (pos <= 0xFF) {
-                               ARM_ADD_REG_IMM8(p, ARMREG_A3, ARMREG_R7, pos);
-                       } else {
-                               if (is_arm_const((armword_t)pos)) {
-                                       shift = calc_arm_mov_const_shift((armword_t)pos);
-                                       ARM_ADD_REG_IMM(p, ARMREG_A3, ARMREG_R7, pos >> ((32 - shift) & 31), shift >> 1);
-                               } else {
-                                       p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_R6, (armword_t)pos);
-                                       ARM_ADD_REG_REG(p, ARMREG_A2, ARMREG_R7, ARMREG_R6);
-                               }
-                       }
-                       arg_pos += sizeof(armword_t);
-                       if (!sig->params[i]->byref) {
-                               switch (sig->params[i]->type) {
-                               case MONO_TYPE_I8:
-                               case MONO_TYPE_U8:
-                               case MONO_TYPE_R8:
-                                       arg_pos += sizeof(armword_t);
-                                       break;
-                               case MONO_TYPE_VALUETYPE:
-                                       /* assert */
-                               default:
-                                       break;
-                               }
-                       }
-               }
-
-               /* A2 = result */
-               if (stackval_pos <= 0xFF) {
-                       ARM_ADD_REG_IMM8(p, ARMREG_A2, ARMREG_SP, stackval_pos);
-               } else {
-                       if (is_arm_const((armword_t)stackval_pos)) {
-                               shift = calc_arm_mov_const_shift((armword_t)stackval_pos);
-                               ARM_ADD_REG_IMM(p, ARMREG_A2, ARMREG_SP, stackval_pos >> ((32 - shift) & 31), shift >> 1);
-                       } else {
-                               p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_R6, (armword_t)stackval_pos);
-                               ARM_ADD_REG_REG(p, ARMREG_A2, ARMREG_SP, ARMREG_R6);
-                       }
-               }
-
-               /* A1 = type */
-               p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_A1, (armword_t)sig->params [i]);
-
-               stackval_pos += ARG_SIZE;
-
-               offs = -(p + 2*sizeof(arminstr_t) - p_stackval_from_data);
-               /* load function address */
-               ARM_LDR_IMM(p, ARMREG_R4, ARMREG_PC, offs);
-               /* call stackval_from_data */
-               ARM_MOV_REG_REG(p, ARMREG_LR, ARMREG_PC);
-               ARM_MOV_REG_REG(p, ARMREG_PC, ARMREG_R4);
-       }
-
-       /* store retval ptr */
-       p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_R5, (armword_t)stackval_pos);
-       ARM_ADD_REG_REG(p, ARMREG_R5, ARMREG_SP, ARMREG_R4);
-       ARM_STR_IMM(p, ARMREG_R5, ARMREG_SP, MINV_OFFS(retval));
-
-       /*
-        * Call the method.
-        */
-       /* A1 = MonoInvocation ptr */
-       ARM_MOV_REG_REG(p, ARMREG_A1, ARMREG_SP);
-       offs = -(p + 2*sizeof(arminstr_t) - p_exec);
-       /* load function address */
-       ARM_LDR_IMM(p, ARMREG_R4, ARMREG_PC, offs);
-       /* call ves_exec */
-       ARM_MOV_REG_REG(p, ARMREG_LR, ARMREG_PC);
-       ARM_MOV_REG_REG(p, ARMREG_PC, ARMREG_R4);
-
-
-       /*
-        * Move retval into reg.
-        */
-       if (sig->ret->byref) {
-               ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R5, 0);
-       } else {
-               switch (sig->ret->type) {
-               case MONO_TYPE_BOOLEAN:
-               case MONO_TYPE_I1:
-               case MONO_TYPE_U1:
-                       ARM_LDRB_IMM(p, ARMREG_R0, ARMREG_R5, 0);
-                       break;
-               case MONO_TYPE_CHAR:
-               case MONO_TYPE_I2:
-               case MONO_TYPE_U2:
-                       ARM_LDRH_IMM(p, ARMREG_R0, ARMREG_R5, 0);
-                       break;
-               case MONO_TYPE_I:
-               case MONO_TYPE_U:
-               case MONO_TYPE_I4:
-               case MONO_TYPE_U4:
-               case MONO_TYPE_R4:
-               case MONO_TYPE_OBJECT:
-               case MONO_TYPE_CLASS:
-               case MONO_TYPE_ARRAY:
-               case MONO_TYPE_SZARRAY:
-                       ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R5, 0);
-                       break;
-               case MONO_TYPE_I8:
-               case MONO_TYPE_U8:
-               case MONO_TYPE_R8:
-                       ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R5, 0);
-                       ARM_LDR_IMM(p, ARMREG_R1, ARMREG_R5, 4);
-                       break;
-               case MONO_TYPE_VOID:
-               default:
-                       break;
-               }
-       }
-
-
-       p = (guchar*)arm_emit_std_epilogue((arminstr_t*)p, stack_size,
-           (1 << ARMREG_R4) |
-           (1 << ARMREG_R5) |
-           (1 << ARMREG_R6) |
-           (1 << ARMREG_R7));
-
-       flush_icache();
-
-#ifdef ARM_DUMP_DISASM
-       _armdis_decode((arminstr_t*)code_buff, ((guint8*)p) - ((guint8*)code_buff));
-#endif
-
-       ji = g_new0(MonoJitInfo, 1);
-       ji->method = method;
-       ji->code_size = ((guint8 *) p) - ((guint8 *) code_buff);
-       ji->code_start = (gpointer) code_buff;
-
-       mono_jit_info_table_add(mono_get_root_domain (), ji);
-
-       return code_buff;
-}
-
-
-/*
- * mono_create_method_pointer () will insert a pointer to the MonoMethod
- * so that the interp can easily get at the data: this function will retrieve 
- * the method from the code stream.
- */
-MonoMethod* mono_method_pointer_get (void* code)
-{
-       unsigned char* c = code;
-       /* check out magic number that follows unconditional branch */
-       if (c[4] == 'M' &&
-           c[5] == 'o' &&
-           c[6] == 'n' &&
-           c[7] == 'o') return ((MonoMethod**)code)[2];
-       return NULL;
-}
-#endif
index c938f9e4bbb9de64fcd9db711cf891aa6fdd6e68..c5d4fbeb70e94f400e7824cc1db1373a6f465094 100644 (file)
@@ -79,11 +79,8 @@ extern gboolean _wapi_handle_count_signalled_handles (guint32 numhandles,
                                                      guint32 *lowest);
 extern void _wapi_handle_unlock_handles (guint32 numhandles,
                                         gpointer *handles);
-extern int _wapi_handle_wait_signal (gboolean poll);
-extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll);
-extern int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable);
-extern int _wapi_handle_timedwait_signal_handle (gpointer handle,
-                                                                                                struct timespec *timeout, gboolean alertable, gboolean poll);
+extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll, gboolean *alerted);
+extern int _wapi_handle_timedwait_signal_handle (gpointer handle, struct timespec *timeout, gboolean alertable, gboolean poll, gboolean *alerted);
 extern gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
                                               guint32 new_sharemode,
                                               guint32 new_access,
index 3ffe49b725d17b4c76c39b7c5bd8f0c765eb1f7a..63d225aab6cfa63cf1e7ad9f665a894e4b54bfb3 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <mono/utils/mono-mutex.h>
 #include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-threads.h>
 #undef DEBUG_REFS
 
 #if 0
@@ -1537,29 +1538,50 @@ static int timedwait_signal_poll_cond (pthread_cond_t *cond, mono_mutex_t *mutex
        return(ret);
 }
 
-int _wapi_handle_wait_signal (gboolean poll)
+int
+_wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll, gboolean *alerted)
 {
-       return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, NULL, TRUE, poll);
+       return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, timeout, TRUE, poll, alerted);
 }
 
-int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll)
+static void
+signal_handle_and_unref (gpointer handle)
 {
-       return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, timeout, TRUE, poll);
-}
+       pthread_cond_t *cond;
+       mono_mutex_t *mutex;
+       guint32 idx;
 
-int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable)
-{
-       DEBUG ("%s: waiting for %p", __func__, handle);
-       
-       return _wapi_handle_timedwait_signal_handle (handle, NULL, alertable, FALSE);
+       g_assert (handle);
+
+       /* If we reach here, then interrupt token is set to the flag value, which
+        * means that the target thread is either
+        * - before the first CAS in timedwait, which means it won't enter the wait.
+        * - it is after the first CAS, so it is already waiting, or it will enter
+        *    the wait, and it will be interrupted by the broadcast. */
+       idx = GPOINTER_TO_UINT (handle);
+       cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
+       mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
+
+       mono_mutex_lock (mutex);
+       mono_cond_broadcast (cond);
+       mono_mutex_unlock (mutex);
+
+       _wapi_handle_unref (handle);
 }
 
-int _wapi_handle_timedwait_signal_handle (gpointer handle,
-                                                                                 struct timespec *timeout, gboolean alertable, gboolean poll)
+int
+_wapi_handle_timedwait_signal_handle (gpointer handle, struct timespec *timeout,
+               gboolean alertable, gboolean poll, gboolean *alerted)
 {
        DEBUG ("%s: waiting for %p (type %s)", __func__, handle,
                   _wapi_handle_typename[_wapi_handle_type (handle)]);
-       
+
+       if (alertable)
+               g_assert (alerted);
+
+       if (alerted)
+               *alerted = FALSE;
+
        if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
                if (WAPI_SHARED_HANDLE_DATA(handle).signalled == TRUE) {
                        return (0);
@@ -1593,8 +1615,12 @@ int _wapi_handle_timedwait_signal_handle (gpointer handle,
                pthread_cond_t *cond;
                mono_mutex_t *mutex;
 
-               if (alertable && !wapi_thread_set_wait_handle (handle))
-                       return 0;
+               if (alertable) {
+                       mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
+                       if (*alerted)
+                               return 0;
+                       _wapi_handle_ref (handle);
+               }
 
                cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
                mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
@@ -1609,8 +1635,13 @@ int _wapi_handle_timedwait_signal_handle (gpointer handle,
                                res = mono_cond_wait (cond, mutex);
                }
 
-               if (alertable)
-                       wapi_thread_clear_wait_handle (handle);
+               if (alertable) {
+                       mono_thread_info_uninstall_interrupt (alerted);
+                       if (!*alerted) {
+                               /* if it is alerted, then the handle is unref in the interrupt callback */
+                               _wapi_handle_unref (handle);
+                       }
+               }
 
                return res;
        }
index ba25cb3730721bd49b13d20b62e9cc35cf6c07f9..685a822749100c2215ded9dd302e080a1d8f5106 100644 (file)
@@ -3420,48 +3420,6 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
        return(TRUE);
 }
 
-guint32 GetTempPath (guint32 len, gunichar2 *buf)
-{
-       gchar *tmpdir=g_strdup (g_get_tmp_dir ());
-       gunichar2 *tmpdir16=NULL;
-       glong dirlen;
-       gsize bytes;
-       guint32 ret;
-       
-       if(tmpdir[strlen (tmpdir)]!='/') {
-               g_free (tmpdir);
-               tmpdir=g_strdup_printf ("%s/", g_get_tmp_dir ());
-       }
-       
-       tmpdir16=mono_unicode_from_external (tmpdir, &bytes);
-       if(tmpdir16==NULL) {
-               g_free (tmpdir);
-               return(0);
-       } else {
-               dirlen=(bytes/2);
-               
-               if(dirlen+1>len) {
-                       DEBUG ("%s: Size %d smaller than needed (%ld)",
-                                  __func__, len, dirlen+1);
-               
-                       ret=dirlen+1;
-               } else {
-                       /* Add the terminator */
-                       memset (buf, '\0', bytes+2);
-                       memcpy (buf, tmpdir16, bytes);
-               
-                       ret=dirlen;
-               }
-       }
-
-       if(tmpdir16!=NULL) {
-               g_free (tmpdir16);
-       }
-       g_free (tmpdir);
-       
-       return(ret);
-}
-
 #ifdef HAVE_GETFSSTAT
 /* Darwin has getfsstat */
 gint32 GetLogicalDriveStrings (guint32 len, gunichar2 *buf)
index e8627764812f3e98632ca244254d96fa7efc823d..12a1310d96784cf7bb40bb5a1c8c6789ebc6b145 100644 (file)
@@ -210,7 +210,6 @@ extern guint32 GetCurrentDirectory (guint32 length, gunichar2 *buffer);
 extern gboolean SetCurrentDirectory (const gunichar2 *path);
 extern gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
                            WapiSecurityAttributes *security, guint32 size);
-extern guint32 GetTempPath (guint32 len, gunichar2 *buf);
 extern gint32 GetLogicalDriveStrings (guint32 len, gunichar2 *buf);
 extern gboolean GetDiskFreeSpaceEx(const gunichar2 *path_name, WapiULargeInteger *free_bytes_avail,
                                   WapiULargeInteger *total_number_of_bytes,
index 5f0805878cf7173c6c492460d6254159a2c3e859..df101ae76a42d42424b56a21f47a2c1f2fb93566 100644 (file)
@@ -554,6 +554,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                        WapiStartupInfo *startup,
                        WapiProcessInformation *process_info)
 {
+#if defined (HAVE_FORK) && defined (HAVE_EXECVE)
        char *cmd = NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL;
        char *dir = NULL, **env_strings = NULL, **argv = NULL;
        guint32 i, env_count = 0;
@@ -1098,6 +1099,10 @@ free_strings:
        mono_processes_cleanup ();
        
        return ret;
+#else
+       SetLastError (ERROR_NOT_SUPPORTED);
+       return FALSE;
+#endif // defined (HAVE_FORK) && defined (HAVE_EXECVE)
 }
                
 static void
@@ -1864,7 +1869,31 @@ get_process_name_from_proc (pid_t pid)
        /* No proc name on OSX < 10.5 nor ppc nor iOS */
        memset (buf, '\0', sizeof(buf));
        proc_name (pid, buf, sizeof(buf));
-       if (strlen (buf) > 0)
+
+       // Fixes proc_name triming values to 15 characters #32539
+       if (strlen (buf) >= MAXCOMLEN - 1) {
+               char path_buf [PROC_PIDPATHINFO_MAXSIZE];
+               char *name_buf;
+               int path_len;
+
+               memset (path_buf, '\0', sizeof(path_buf));
+               path_len = proc_pidpath (pid, path_buf, sizeof(path_buf));
+
+               if (path_len > 0 && path_len < sizeof(path_buf)) {
+                       name_buf = path_buf + path_len;
+                       for(;name_buf > path_buf; name_buf--) {
+                               if (name_buf [0] == '/') {
+                                       name_buf++;
+                                       break;
+                               }
+                       }
+
+                       if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0)
+                               ret = g_strdup (name_buf);
+               }
+       }
+
+       if (ret == NULL && strlen (buf) > 0)
                ret = g_strdup (buf);
 #else
        if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
@@ -2171,6 +2200,53 @@ get_module_name (gpointer process, gpointer module,
        return 0;
 }
 
+static guint32
+get_module_filename (gpointer process, gpointer module,
+                                        gunichar2 *basename, guint32 size)
+{
+       int pid, len;
+       gsize bytes;
+       char *path;
+       gunichar2 *proc_path;
+       
+       size *= sizeof (gunichar2); /* adjust for unicode characters */
+
+       if (basename == NULL || size == 0)
+               return 0;
+
+       pid = GetProcessId (process);
+
+       path = wapi_process_get_path (pid);
+       if (path == NULL)
+               return 0;
+
+       proc_path = mono_unicode_from_external (path, &bytes);
+       g_free (path);
+
+       if (proc_path == NULL)
+               return 0;
+
+       len = (bytes / 2);
+       
+       /* Add the terminator */
+       bytes += 2;
+
+       if (size < bytes) {
+               DEBUG ("%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
+
+               memcpy (basename, proc_path, size);
+       } else {
+               DEBUG ("%s: Size %d larger than needed (%ld)",
+                          __func__, size, bytes);
+
+               memcpy (basename, proc_path, bytes);
+       }
+
+       g_free (proc_path);
+
+       return len;
+}
+
 guint32
 GetModuleBaseName (gpointer process, gpointer module,
                                   gunichar2 *basename, guint32 size)
@@ -2182,7 +2258,7 @@ guint32
 GetModuleFileNameEx (gpointer process, gpointer module,
                                         gunichar2 *filename, guint32 size)
 {
-       return get_module_name (process, module, filename, size, FALSE);
+       return get_module_filename (process, module, filename, size);
 }
 
 gboolean
index e9f8f9c8813af499e66b6191b97b1c37e6c400c8..3ea1af1197884f7efaa31af5c52d7e52b970c7d5 100644 (file)
 
 extern struct _WapiHandleOps _wapi_thread_ops;
 
-#define INTERRUPTION_REQUESTED_HANDLE (gpointer)0xFFFFFFFE
-
 struct _WapiHandle_thread
 {
        pthread_t id;
        GPtrArray *owned_mutexes;
-       /* 
-     * Handle this thread waits on. If this is INTERRUPTION_REQUESTED_HANDLE,
-        * it means the thread is interrupted by another thread, and shouldn't enter
-        * a wait.
-        * This also acts as a reference for the handle.
-        */
-       gpointer wait_handle;
 };
 
 typedef struct _WapiHandle_thread WapiHandle_thread;
 
-extern gboolean _wapi_thread_apc_pending (gpointer handle);
 extern gboolean _wapi_thread_cur_apc_pending (void);
 extern void _wapi_thread_own_mutex (gpointer mutex);
 extern void _wapi_thread_disown_mutex (gpointer mutex);
index 13b6bd1401f0b9192d258690f512272d7176e71e..a756a40fb64a7f42dd96e4b70bcda5252afd34eb 100644 (file)
@@ -30,14 +30,6 @@ extern gsize GetCurrentThreadId(void); /* NB return is 32bit in MS API */
 extern void Sleep(guint32 ms);
 extern guint32 SleepEx(guint32 ms, gboolean alertable);
 
-void wapi_clear_interruption (void);
-gboolean wapi_thread_set_wait_handle (gpointer handle);
-void wapi_thread_clear_wait_handle (gpointer handle);
-void wapi_self_interrupt (void);
-
-gpointer wapi_prepare_interrupt_thread (gpointer thread_handle);
-void wapi_finish_interrupt_thread (gpointer wait_handle);
-
 gpointer wapi_create_thread_handle (void);
 void wapi_thread_handle_set_exited (gpointer handle, guint32 exitstatus);
 void wapi_ref_thread_handle (gpointer handle);
index 8bdf39bdbf8ac54d05257c7365b73feb8b902b94..42fc96fe4fb6ad14bdeb451437b48b1bc0b0ac53 100644 (file)
@@ -130,12 +130,10 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
 
                ret = _wapi_handle_ops_special_wait (handle, timeout, alertable);
        
-               if (alertable && _wapi_thread_apc_pending (current_thread)) {
-                       apc_pending = TRUE;
+               if (alertable && _wapi_thread_cur_apc_pending ())
                        ret = WAIT_IO_COMPLETION;
-               }
 
-               goto check_pending;
+               return ret;
        }
        
        
@@ -153,13 +151,7 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
                        goto done;
                }
        }
-       
-       if (alertable && _wapi_thread_apc_pending (current_thread)) {
-               apc_pending = TRUE;
-               ret = WAIT_IO_COMPLETION;
-               goto done;
-       }
-       
+
        if (own_if_signalled (handle) == TRUE) {
                DEBUG ("%s: handle %p already signalled", __func__,
                           handle);
@@ -189,15 +181,8 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
                        ret = WAIT_OBJECT_0;
                        goto done;
                }
-                       
-               if (timeout == INFINITE) {
-                       waited = _wapi_handle_wait_signal_handle (handle, alertable);
-               } else {
-                       waited = _wapi_handle_timedwait_signal_handle (handle, &abstime, alertable, FALSE);
-               }
-       
-               if (alertable)
-                       apc_pending = _wapi_thread_apc_pending (current_thread);
+
+               waited = _wapi_handle_timedwait_signal_handle (handle, timeout == INFINITE ? NULL : &abstime, alertable, FALSE, &apc_pending);
 
                if(waited==0 && !apc_pending) {
                        /* Condition was signalled, so hopefully
@@ -220,19 +205,15 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
        DEBUG ("%s: wait on handle %p error: %s", __func__, handle,
                   strerror (waited));
 
-       ret = WAIT_TIMEOUT;
-       
+       ret = apc_pending ? WAIT_IO_COMPLETION : WAIT_TIMEOUT;
+
 done:
 
        DEBUG ("%s: unlocking handle %p", __func__, handle);
        
        thr_ret = _wapi_handle_unlock_handle (handle);
        g_assert (thr_ret == 0);
-       
-check_pending:
-       if (apc_pending)
-               ret = WAIT_IO_COMPLETION;
-               
+
        return(ret);
 }
 
@@ -351,13 +332,7 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                        goto done;
                }
        }
-       
-       if (alertable && _wapi_thread_apc_pending (current_thread)) {
-               apc_pending = TRUE;
-               ret = WAIT_IO_COMPLETION;
-               goto done;
-       }
-       
+
        if (own_if_signalled (wait)) {
                DEBUG ("%s: handle %p already signalled", __func__, wait);
 
@@ -381,16 +356,8 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                        ret = WAIT_OBJECT_0;
                        goto done;
                }
-               
-               if (timeout == INFINITE) {
-                       waited = _wapi_handle_wait_signal_handle (wait, alertable);
-               } else {
-                       waited = _wapi_handle_timedwait_signal_handle (wait, &abstime, alertable, FALSE);
-               }
 
-               if (alertable) {
-                       apc_pending = _wapi_thread_apc_pending (current_thread);
-               }
+               waited = _wapi_handle_timedwait_signal_handle (wait, timeout == INFINITE ? NULL : &abstime, alertable, FALSE, &apc_pending);
 
                if (waited==0 && !apc_pending) {
                        /* Condition was signalled, so hopefully
@@ -413,8 +380,8 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
        DEBUG ("%s: wait on handle %p error: %s", __func__, wait,
                   strerror (ret));
 
-       ret = WAIT_TIMEOUT;
-       
+       ret = apc_pending ? WAIT_IO_COMPLETION : WAIT_TIMEOUT;
+
 done:
 
        DEBUG ("%s: unlocking handle %p", __func__, wait);
@@ -422,9 +389,6 @@ done:
        thr_ret = _wapi_handle_unlock_handle (wait);
        g_assert (thr_ret == 0);
 
-       if (apc_pending)
-               ret = WAIT_IO_COMPLETION;
-       
        return(ret);
 }
 
@@ -500,6 +464,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
        guint32 retval;
        gboolean poll;
        gpointer sorted_handles [MAXIMUM_WAIT_OBJECTS];
+       gboolean apc_pending = FALSE;
        
        if (current_thread == NULL) {
                SetLastError (ERROR_INVALID_HANDLE);
@@ -590,9 +555,6 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                _wapi_calc_timeout (&abstime, timeout);
        }
 
-       if (alertable && _wapi_thread_apc_pending (current_thread))
-               return WAIT_IO_COMPLETION;
-       
        for (i = 0; i < numobjects; i++) {
                /* Add a reference, as we need to ensure the handle wont
                 * disappear from under us while we're waiting in the loop
@@ -633,11 +595,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                
                if (!done) {
                        /* Enter the wait */
-                       if (timeout == INFINITE) {
-                               ret = _wapi_handle_wait_signal (poll);
-                       } else {
-                               ret = _wapi_handle_timedwait_signal (&abstime, poll);
-                       }
+                       ret = _wapi_handle_timedwait_signal (timeout == INFINITE ? NULL : &abstime, poll, &apc_pending);
                } else {
                        /* No need to wait */
                        ret = 0;
@@ -648,7 +606,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                thr_ret = _wapi_handle_unlock_signal_mutex (NULL);
                g_assert (thr_ret == 0);
                
-               if (alertable && _wapi_thread_apc_pending (current_thread)) {
+               if (alertable && apc_pending) {
                        retval = WAIT_IO_COMPLETION;
                        break;
                }
index 6db10c716ab4b526b485d03e429b550b75965df8..123755888b590792818522f1d80016c2525a74e9 100644 (file)
@@ -50,7 +50,6 @@
 #define GetCurrentDirectory wapi_GetCurrentDirectory 
 #define SetCurrentDirectory wapi_SetCurrentDirectory 
 #define CreatePipe wapi_CreatePipe 
-#define GetTempPath wapi_GetTempPath 
 #define GetLogicalDriveStrings wapi_GetLogicalDriveStrings 
 #define GetDiskFreeSpaceEx wapi_GetDiskFreeSpaceEx
 #define GetDriveType wapi_GetDriveType
index 90a8cc4ffa855b6690c0895b78f9778b096f8b1b..910cb9af35920e3edf5933eb1939a13ea0bc4a09 100644 (file)
@@ -243,7 +243,7 @@ SleepEx (guint32 ms, gboolean alertable)
        if (alertable) {
                current_thread = get_current_thread_handle ();
                
-               if (_wapi_thread_apc_pending (current_thread))
+               if (_wapi_thread_cur_apc_pending ())
                        return WAIT_IO_COMPLETION;
        }
        
@@ -271,7 +271,7 @@ SleepEx (guint32 ms, gboolean alertable)
        while (TRUE) {
                ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL);
 
-               if (alertable && _wapi_thread_apc_pending (current_thread))
+               if (alertable && _wapi_thread_cur_apc_pending ())
                        return WAIT_IO_COMPLETION;
 
                if (ret == 0)
@@ -288,7 +288,7 @@ again:
        memset (&rem, 0, sizeof (rem));
        ret=nanosleep(&req, &rem);
 
-       if (alertable && _wapi_thread_apc_pending (current_thread))
+       if (alertable && _wapi_thread_cur_apc_pending ())
                return WAIT_IO_COMPLETION;
        
        if(ret==-1) {
@@ -316,182 +316,7 @@ Sleep(guint32 ms)
 gboolean
 _wapi_thread_cur_apc_pending (void)
 {
-       return _wapi_thread_apc_pending (get_current_thread_handle ());
-}
-
-gboolean
-_wapi_thread_apc_pending (gpointer handle)
-{
-       WapiHandle_thread *thread;
-
-       thread = lookup_thread (handle);
-       
-       return thread->wait_handle == INTERRUPTION_REQUESTED_HANDLE;
-}
-
-/*
- * wapi_interrupt_thread:
- *
- * The state of the thread handle HANDLE is set to 'interrupted' which means that
- * if the thread calls one of the WaitFor functions, the function will return with 
- * WAIT_IO_COMPLETION instead of waiting. Also, if the thread was waiting when
- * this function was called, the wait will be broken.
- * It is possible that the wait functions return WAIT_IO_COMPLETION, but the
- * target thread didn't receive the interrupt signal yet, in this case it should
- * call the wait function again. This essentially means that the target thread will
- * busy wait until it is ready to process the interruption.
- */
-gpointer
-wapi_prepare_interrupt_thread (gpointer thread_handle)
-{
-       WapiHandle_thread *thread;
-       gpointer prev_handle, wait_handle;
-
-       thread = lookup_thread (thread_handle); /* FIXME this is wrong, move this whole thing to MonoThreads where it can be done lockfree */
-
-       while (TRUE) {
-               wait_handle = thread->wait_handle;
-
-               /* 
-                * Atomically obtain the handle the thread is waiting on, and
-                * change it to a flag value.
-                */
-               prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
-                                                                                                                INTERRUPTION_REQUESTED_HANDLE, wait_handle);
-               if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
-                       /* Already interrupted */
-                       return 0;
-               if (prev_handle == wait_handle)
-                       break;
-
-               /* Try again */
-       }
-
-       WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread->id););
-
-       return wait_handle;
-}
-
-void
-wapi_finish_interrupt_thread (gpointer wait_handle)
-{
-       pthread_cond_t *cond;
-       mono_mutex_t *mutex;
-       guint32 idx;
-
-       if (!wait_handle)
-               /* Not waiting */
-               return;
-
-       /* If we reach here, then wait_handle is set to the flag value, 
-        * which means that the target thread is either
-        * - before the first CAS in timedwait, which means it won't enter the
-        * wait.
-        * - it is after the first CAS, so it is already waiting, or it will 
-        * enter the wait, and it will be interrupted by the broadcast.
-        */
-       idx = GPOINTER_TO_UINT(wait_handle);
-       cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
-       mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
-
-       mono_mutex_lock (mutex);
-       mono_cond_broadcast (cond);
-       mono_mutex_unlock (mutex);
-
-       /* ref added by set_wait_handle */
-       _wapi_handle_unref (wait_handle);
-}
-
-/*
- * wapi_self_interrupt:
- *
- *   This is not part of the WIN32 API.
- * Set the 'interrupted' state of the calling thread if it's NULL.
- */
-void
-wapi_self_interrupt (void)
-{
-       gpointer wait_handle;
-
-       wait_handle = wapi_prepare_interrupt_thread (get_current_thread_handle ());
-       if (wait_handle)
-               /* ref added by set_wait_handle */
-               _wapi_handle_unref (wait_handle);
-}
-
-/*
- * wapi_clear_interruption:
- *
- *   This is not part of the WIN32 API. 
- * Clear the 'interrupted' state of the calling thread.
- * This function is signal safe
- */
-void
-wapi_clear_interruption (void)
-{
-       WapiHandle_thread *thread;
-       gpointer prev_handle;
-
-       thread = get_current_thread ();
-
-       prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
-                                                                                                        NULL, INTERRUPTION_REQUESTED_HANDLE);
-       if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
-               WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
-}
-
-/**
- * wapi_thread_set_wait_handle:
- *
- *   Set the wait handle for the current thread to HANDLE. Return TRUE on success, FALSE
- * if the thread is in interrupted state, and cannot start waiting.
- */
-gboolean
-wapi_thread_set_wait_handle (gpointer handle)
-{
-       WapiHandle_thread *thread;
-       gpointer prev_handle;
-
-       thread = get_current_thread ();
-
-       prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
-                                                                                                        handle, NULL);
-       if (prev_handle == NULL) {
-               /* thread->wait_handle acts as an additional reference to the handle */
-               _wapi_handle_ref (handle);
-
-               WAIT_DEBUG (printf ("%p: state -> WAITING.\n", GetCurrentThreadId ()););
-       } else {
-               g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
-               WAIT_DEBUG (printf ("%p: unable to set state to WAITING.\n", GetCurrentThreadId ()););
-       }
-
-       return prev_handle == NULL;
-}
-
-/**
- * wapi_thread_clear_wait_handle:
- *
- *   Clear the wait handle of the current thread.
- */
-void
-wapi_thread_clear_wait_handle (gpointer handle)
-{
-       WapiHandle_thread *thread;
-       gpointer prev_handle;
-
-       thread = get_current_thread ();
-
-       prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
-                                                                                                        NULL, handle);
-       if (prev_handle == handle) {
-               _wapi_handle_unref (handle);
-               WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
-       } else {
-               /*It can be NULL if it was asynchronously cleared*/
-               g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE || prev_handle == NULL);
-               WAIT_DEBUG (printf ("%p: finished waiting.\n", GetCurrentThreadId ()););
-       }
+       return mono_thread_info_is_interrupt_state (mono_thread_info_current ());
 }
 
 void
@@ -524,31 +349,20 @@ wapi_current_thread_desc (void)
        WapiHandle_thread *thread;
        gpointer thread_handle;
        int i;
-       gpointer handle;
        GString* text;
        char *res;
 
        thread_handle = get_current_thread_handle ();
        thread = lookup_thread (thread_handle);
 
-       handle = thread->wait_handle;
        text = g_string_new (0);
        g_string_append_printf (text, "thread handle %p state : ", thread_handle);
 
-       if (!handle)
-               g_string_append_printf (text, "not waiting");
-       else if (handle == INTERRUPTION_REQUESTED_HANDLE)
-               g_string_append_printf (text, "interrupted state");
-       else
-               g_string_append_printf (text, "waiting on %p : %s ", handle, _wapi_handle_typename[_wapi_handle_type (handle)]);
+       mono_thread_info_describe_interrupt_token (mono_thread_info_current (), text);
+
        g_string_append_printf (text, " owns (");
-       for (i = 0; i < thread->owned_mutexes->len; i++) {
-               gpointer mutex = g_ptr_array_index (thread->owned_mutexes, i);
-               if (i > 0)
-                       g_string_append_printf (text, ", %p", mutex);
-               else
-                       g_string_append_printf (text, "%p", mutex);
-       }
+       for (i = 0; i < thread->owned_mutexes->len; i++)
+               g_string_append_printf (text, i > 0 ? ", %p" : "%p", g_ptr_array_index (thread->owned_mutexes, i));
        g_string_append_printf (text, ")");
 
        res = text->str;
index 460c7ec00c96394aa2f58e27ebcc00fcf3c3718a..d0e6fc2fa576554f18eb5aa1984da3d40d3f4d17 100644 (file)
@@ -234,6 +234,7 @@ sgen_sources = \
        sgen-os-posix.c         \
        sgen-os-mach.c          \
        sgen-os-win32.c         \
+       sgen-os-coop.c          \
        sgen-bridge.c           \
        sgen-bridge.h           \
        sgen-bridge-internal.h  \
index 8c9320e29d599d54bb6e86842f87ff176040b3dc..5a9433d6b67fcbf3df89c65fea4634435602aa37 100644 (file)
@@ -79,7 +79,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 135
+#define MONO_CORLIB_VERSION 136
 
 typedef struct
 {
@@ -89,8 +89,6 @@ typedef struct
        gchar *filename;
 } RuntimeConfig;
 
-mono_mutex_t mono_delegate_section;
-
 static gunichar2 process_guid [36];
 static gboolean process_guid_set = FALSE;
 
@@ -255,8 +253,6 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        domain->domain = ad;
        domain->setup = setup;
 
-       mono_mutex_init_recursive (&mono_delegate_section);
-       
        mono_thread_attach (domain);
 
        mono_type_initialization_init ();
@@ -624,9 +620,9 @@ ves_icall_System_AppDomain_GetData (MonoAppDomain *ad, MonoString *name)
 
        MONO_CHECK_ARG_NULL (name, NULL);
 
-       g_assert (ad != NULL);
+       g_assert (ad);
        add = ad->data;
-       g_assert (add != NULL);
+       g_assert (add);
 
        str = mono_string_to_utf8 (name);
 
@@ -669,9 +665,9 @@ ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObj
 
        MONO_CHECK_ARG_NULL (name,);
 
-       g_assert (ad != NULL);
+       g_assert (ad);
        add = ad->data;
-       g_assert (add != NULL);
+       g_assert (add);
 
        mono_domain_lock (add);
 
@@ -683,8 +679,8 @@ ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObj
 MonoAppDomainSetup *
 ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
 {
-       g_assert (ad != NULL);
-       g_assert (ad->data != NULL);
+       g_assert (ad);
+       g_assert (ad->data);
 
        return ad->data->setup;
 }
@@ -692,8 +688,8 @@ ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
 MonoString *
 ves_icall_System_AppDomain_getFriendlyName (MonoAppDomain *ad)
 {
-       g_assert (ad != NULL);
-       g_assert (ad->data != NULL);
+       g_assert (ad);
+       g_assert (ad->data);
 
        return mono_string_new (ad->data, ad->data->friendly_name);
 }
@@ -1962,7 +1958,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
        gchar *name;
        gboolean parsed;
 
-       g_assert (assRef != NULL);
+       g_assert (assRef);
 
        name = mono_string_to_utf8 (assRef);
        parsed = mono_assembly_name_parse (name, &aname);
@@ -2366,9 +2362,9 @@ guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
 {
        guint32 result;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        result = WaitForSingleObjectEx (handle, timeout, alertable);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        return result;
 }
index bd887b84f22b620cec97e9db216d7e5708d8cd99..45038289621a96ef7e59243a0f0d311c988e586b 100644 (file)
@@ -88,6 +88,8 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"I18N.Other", 0},
        {"I18N.Rare", 0},
        {"I18N.West", 0},
+       {"Microsoft.Build.Engine", 2},
+       {"Microsoft.Build.Framework", 2},
        {"Microsoft.VisualBasic", 1},
        {"Microsoft.VisualC", 1},
        {"Mono.Cairo", 0},
@@ -177,6 +179,8 @@ mono_set_corlib_data (void *data, size_t size)
 
 #endif
 
+static char* unquote (const char *str);
+
 /* This protects loaded_assemblies and image->references */
 #define mono_assemblies_lock() mono_mutex_lock (&assemblies_mutex)
 #define mono_assemblies_unlock() mono_mutex_unlock (&assemblies_mutex)
@@ -2076,11 +2080,19 @@ gboolean
 mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboolean save_public_key, gboolean *is_version_defined, gboolean *is_token_defined)
 {
        gchar *dllname;
+       gchar *dllname_uq;
        gchar *version = NULL;
+       gchar *version_uq;
        gchar *culture = NULL;
+       gchar *culture_uq;
        gchar *token = NULL;
+       gchar *token_uq;
        gchar *key = NULL;
+       gchar *key_uq;
        gchar *retargetable = NULL;
+       gchar *retargetable_uq;
+       gchar *procarch;
+       gchar *procarch_uq;
        gboolean res;
        gchar *value, *part_name;
        guint32 part_name_len;
@@ -2152,29 +2164,42 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole
 
                if (part_name_len == 12 && !g_ascii_strncasecmp (part_name, "Retargetable", part_name_len)) {
                        retargetable = value;
-                       if (strlen (retargetable) == 0) {
-                               goto cleanup_and_fail;
-                       }
+                       retargetable_uq = unquote (retargetable);
+                       if (retargetable_uq != NULL)
+                               retargetable = retargetable_uq;
+
                        if (!g_ascii_strcasecmp (retargetable, "yes")) {
                                flags |= ASSEMBLYREF_RETARGETABLE_FLAG;
                        } else if (g_ascii_strcasecmp (retargetable, "no")) {
+                               free (retargetable_uq);
                                goto cleanup_and_fail;
                        }
+
+                       free (retargetable_uq);
                        tmp++;
                        continue;
                }
 
                if (part_name_len == 21 && !g_ascii_strncasecmp (part_name, "ProcessorArchitecture", part_name_len)) {
-                       if (!g_ascii_strcasecmp (value, "MSIL"))
+                       procarch = value;
+                       procarch_uq = unquote (procarch);
+                       if (procarch_uq != NULL)
+                               procarch = procarch_uq;
+
+                       if (!g_ascii_strcasecmp (procarch, "MSIL"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_MSIL;
-                       else if (!g_ascii_strcasecmp (value, "X86"))
+                       else if (!g_ascii_strcasecmp (procarch, "X86"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_X86;
-                       else if (!g_ascii_strcasecmp (value, "IA64"))
+                       else if (!g_ascii_strcasecmp (procarch, "IA64"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_IA64;
-                       else if (!g_ascii_strcasecmp (value, "AMD64"))
+                       else if (!g_ascii_strcasecmp (procarch, "AMD64"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_AMD64;
-                       else
+                       else {
+                               free (procarch_uq);
                                goto cleanup_and_fail;
+                       }
+
+                       free (procarch_uq);
                        tmp++;
                        continue;
                }
@@ -2188,8 +2213,26 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole
                goto cleanup_and_fail;
        }
 
-       res = build_assembly_name (dllname, version, culture, token, key, flags, arch,
-               aname, save_public_key);
+       dllname_uq = unquote (dllname);
+       version_uq = unquote (version);
+       culture_uq = unquote (culture);
+       token_uq = unquote (token);
+       key_uq = unquote (key);
+
+       res = build_assembly_name (
+               dllname_uq == NULL ? dllname : dllname_uq,
+               version_uq == NULL ? version : version_uq,
+               culture_uq == NULL ? culture : culture_uq,
+               token_uq == NULL ? token : token_uq,
+               key_uq == NULL ? key : key_uq,
+               flags, arch, aname, save_public_key);
+
+       free (dllname_uq);
+       free (version_uq);
+       free (culture_uq);
+       free (token_uq);
+       free (key_uq);
+
        g_strfreev (parts);
        return res;
 
@@ -2198,6 +2241,29 @@ cleanup_and_fail:
        return FALSE;
 }
 
+static char*
+unquote (const char *str)
+{
+       gint slen;
+       const char *end;
+
+       if (str == NULL)
+               return NULL;
+
+       slen = strlen (str);
+       if (slen < 2)
+               return NULL;
+
+       if (*str != '\'' && *str != '\"')
+               return NULL;
+
+       end = str + slen - 1;
+       if (*str != *end)
+               return NULL;
+
+       return g_strndup (str + 1, slen - 2);
+}
+
 /**
  * mono_assembly_name_parse:
  * @name: name to parse
index ca5f3b54227c060ab8dd17055cca9ca85d1afd93..46ea5ef635098895a28624e2a0dc101d5418e1da 100644 (file)
@@ -82,8 +82,6 @@ struct _MonoMethod {
        unsigned int is_inflated:1; /* whether we're a MonoMethodInflated */
        unsigned int skip_visibility:1; /* whenever to skip JIT visibility checks */
        unsigned int verification_success:1; /* whether this method has been verified successfully.*/
-       /* TODO we MUST get rid of this field, it's an ugly hack nobody is proud of. */
-       unsigned int is_mb_open : 1;            /* This is the fully open instantiation of a generic method_builder. Worse than is_tb_open, but it's temporary */
        signed int slot : 16;
 
        /*
index fef85ef11fdec152238fea699bf56750d06d556b..04b597af1398c1c904ba7975f78472d42497bd64 100644 (file)
@@ -1009,7 +1009,6 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
        MonoMethodInflated *iresult, *cached;
        MonoMethodSignature *sig;
        MonoGenericContext tmp_context;
-       gboolean is_mb_open = FALSE;
 
        mono_error_init (error);
 
@@ -1041,44 +1040,9 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
                (method->klass->generic_container && context->class_inst)))
                return method;
 
-       /*
-        * The reason for this hack is to fix the behavior of inflating generic methods that come from a MethodBuilder.
-        * What happens is that instantiating a generic MethodBuilder with its own arguments should create a diferent object.
-        * This is opposite to the way non-SRE MethodInfos behave.
-        * 
-        * This happens, for example, when we want to emit a recursive generic method. Given the following C# code:
-        * 
-        * void Example<T> () {
-        *    Example<T> ();
-        * }
-        *  
-        * In Example, the method token must be encoded as: "void Example<!!0>()"
-        * 
-        * The reference to the first generic argument, "!!0", must be explicit otherwise it won't be inflated
-        * properly. To get that we need to inflate the MethodBuilder with its own arguments.
-        * 
-        * On the other hand, inflating a non-SRE generic method with its own arguments should
-        * return itself. For example:
-        * 
-        * MethodInfo m = ... //m is a generic method definition
-        * MethodInfo res = m.MakeGenericMethod (m.GetGenericArguments ());
-        * res == m
-        *
-        * To allow such scenarios we must allow inflation of MethodBuilder to happen in a diferent way than
-        * what happens with regular methods.
-        * 
-        * There is one last touch to this madness, once a TypeBuilder is finished, IOW CreateType() is called,
-        * everything should behave like a regular type or method.
-        * 
-        */
-       is_mb_open = method->is_generic &&
-               image_is_dynamic (method->klass->image) && !method->klass->wastypebuilder && /* that is a MethodBuilder from an unfinished TypeBuilder */
-               context->method_inst == mono_method_get_generic_container (method)->context.method_inst; /* and it's been instantiated with its own arguments.  */
-
        iresult = g_new0 (MonoMethodInflated, 1);
        iresult->context = *context;
        iresult->declaring = method;
-       iresult->method.method.is_mb_open = is_mb_open;
 
        if (!context->method_inst && method->is_generic)
                iresult->context.method_inst = mono_method_get_generic_container (method)->context.method_inst;
@@ -1129,7 +1093,6 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
        result->is_generic = FALSE;
        result->sre_method = FALSE;
        result->signature = NULL;
-       result->is_mb_open = is_mb_open;
 
        if (!context->method_inst) {
                /* Set the generic_container of the result to the generic_container of method */
@@ -7483,17 +7446,16 @@ mono_image_init_name_cache (MonoImage *image)
        if (image->name_cache)
                return;
 
-       mono_image_lock (image);
-
-       if (image->name_cache) {
-               mono_image_unlock (image);
-               return;
-       }
-
        the_name_cache = g_hash_table_new (g_str_hash, g_str_equal);
 
        if (image_is_dynamic (image)) {
-               mono_atomic_store_release (&image->name_cache, the_name_cache);
+               mono_image_lock (image);
+               if (image->name_cache) {
+                       /* Somebody initialized it before us */
+                       g_hash_table_destroy (the_name_cache);
+               } else {
+                       mono_atomic_store_release (&image->name_cache, the_name_cache);
+               }
                mono_image_unlock (image);
                return;
        }
@@ -7548,7 +7510,12 @@ mono_image_init_name_cache (MonoImage *image)
        }
 
        g_hash_table_destroy (name_cache2);
-       mono_atomic_store_release (&image->name_cache, the_name_cache);
+       if (image->name_cache) {
+               /* Somebody initialized it before us */
+               g_hash_table_destroy (the_name_cache);
+       } else {
+               mono_atomic_store_release (&image->name_cache, the_name_cache);
+       }
        mono_image_unlock (image);
 }
 
@@ -7728,7 +7695,7 @@ search_modules (MonoImage *image, const char *name_space, const char *name)
 }
 
 static MonoClass *
-mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, MonoGHashTable* visited_images)
+mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, GHashTable* visited_images)
 {
        GHashTable *nspace_table;
        MonoImage *loaded_image;
@@ -7741,10 +7708,10 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons
        mono_error_init (error);
 
        // Checking visited images avoids stack overflows when cyclic references exist.
-       if (mono_g_hash_table_lookup (visited_images, image))
+       if (g_hash_table_lookup (visited_images, image))
                return NULL;
 
-       mono_g_hash_table_insert (visited_images, image, GUINT_TO_POINTER(1));
+       g_hash_table_insert (visited_images, image, GUINT_TO_POINTER(1));
 
        if ((nested = strchr (name, '/'))) {
                int pos = nested - name;
@@ -7846,13 +7813,13 @@ MonoClass *
 mono_class_from_name_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error)
 {
        MonoClass *klass;
-       MonoGHashTable *visited_images;
+       GHashTable *visited_images;
 
-       visited_images = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
+       visited_images = g_hash_table_new (g_direct_hash, g_direct_equal);
 
        klass = mono_class_from_name_checked_aux (image, name_space, name, error, visited_images);
 
-       mono_g_hash_table_destroy (visited_images);
+       g_hash_table_destroy (visited_images);
 
        return klass;
 }
index b70d40695886a845801f4de7096dab6605952052..873770b436abd3d9b4807b24ce46aca308403fc8 100644 (file)
@@ -16,9 +16,6 @@
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/mempool-internals.h>
 
-
-extern mono_mutex_t mono_delegate_section;
-
 /*
  * If this is set, the memory belonging to appdomains is not freed when a domain is
  * unloaded, and assemblies loaded by the appdomain are not unloaded either. This
@@ -403,6 +400,9 @@ struct _MonoDomain {
        /* that require wrappers */
        GHashTable *ftnptrs_hash;
 
+       /* Maps MonoMethod* to weak links to DynamicMethod objects */
+       GHashTable *method_to_dyn_method;
+
        guint32 execution_context_field_offset;
 };
 
old mode 100755 (executable)
new mode 100644 (file)
index 24df067..9bf4c49
@@ -93,7 +93,12 @@ static gboolean debug_domain_unload;
 
 gboolean mono_dont_free_domains;
 
-#define mono_appdomains_lock() mono_mutex_lock (&appdomains_mutex)
+#define mono_appdomains_lock() do {    \
+       MONO_TRY_BLOCKING;      \
+       mono_mutex_lock (&appdomains_mutex); \
+       MONO_FINISH_TRY_BLOCKING;       \
+} while (0);
+
 #define mono_appdomains_unlock() mono_mutex_unlock (&appdomains_mutex)
 static mono_mutex_t appdomains_mutex;
 
@@ -486,7 +491,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        MonoAssembly *ass = NULL;
        MonoImageOpenStatus status = MONO_IMAGE_OK;
        const MonoRuntimeInfo* runtimes [G_N_ELEMENTS (supported_runtimes) + 1];
-       int n;
+       int n, dummy;
 
 #ifdef DEBUG_DOMAIN_UNLOAD
        debug_domain_unload = TRUE;
@@ -514,6 +519,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        mono_counters_register ("Total code space allocated", MONO_COUNTER_INT|MONO_COUNTER_JIT, &total_domain_code_alloc);
 
        mono_gc_base_init ();
+       mono_thread_info_attach (&dummy);
 
        MONO_FAST_TLS_INIT (tls_appdomain);
        mono_native_tls_alloc (&appdomain_thread_id, NULL);
@@ -1282,6 +1288,10 @@ mono_domain_free (MonoDomain *domain, gboolean force)
                g_hash_table_destroy (domain->ftnptrs_hash);
                domain->ftnptrs_hash = NULL;
        }
+       if (domain->method_to_dyn_method) {
+               g_hash_table_destroy (domain->method_to_dyn_method);
+               domain->method_to_dyn_method = NULL;
+       }
 
        mono_mutex_destroy (&domain->finalizable_objects_hash_lock);
        mono_mutex_destroy (&domain->assemblies_lock);
@@ -1959,9 +1969,9 @@ mono_get_aot_cache_config (void)
 void
 mono_domain_lock (MonoDomain *domain)
 {
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_locks_acquire (&(domain)->lock, DomainLock);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 }
 
 void
index c4bb6df67659c364a42f5a2a2c47943bea43b63c..fec434715b57dd6b963524948abf281552d5fed5 100644 (file)
@@ -269,7 +269,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -278,7 +278,7 @@ ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -286,7 +286,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -295,25 +295,25 @@ ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
 static gchar *
-get_search_dir (MonoString *pattern)
+get_search_dir (const gunichar2 *pattern)
 {
        gchar *p;
        gchar *result;
 
-       p = mono_string_to_utf8 (pattern);
+       p = g_utf16_to_utf8 (pattern, -1, NULL, NULL, NULL);
        result = g_path_get_dirname (p);
        g_free (p);
        return result;
 }
 
 static GPtrArray *
-get_filesystem_entries (MonoString *path,
-                                                MonoString *path_with_pattern,
+get_filesystem_entries (const gunichar2 *path,
+                                                const gunichar2 *path_with_pattern,
                                                 gint attrs, gint mask,
                                                 gint32 *error)
 {
@@ -325,7 +325,7 @@ get_filesystem_entries (MonoString *path,
        gint32 attributes;
 
        mask = convert_attrs (mask);
-       attributes = get_file_attributes (mono_string_chars (path));
+       attributes = get_file_attributes (path);
        if (attributes != -1) {
                if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
                        *error = ERROR_INVALID_NAME;
@@ -336,7 +336,7 @@ get_filesystem_entries (MonoString *path,
                goto fail;
        }
        
-       find_handle = FindFirstFile (mono_string_chars (path_with_pattern), &data);
+       find_handle = FindFirstFile (path_with_pattern, &data);
        if (find_handle == INVALID_HANDLE_VALUE) {
                gint32 find_error = GetLastError ();
                
@@ -402,9 +402,9 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
        
        *error = ERROR_SUCCESS;
 
-       MONO_PREPARE_BLOCKING
-       names = get_filesystem_entries (path, path_with_pattern, attrs, mask, error);
-       MONO_FINISH_BLOCKING
+       MONO_PREPARE_BLOCKING;
+       names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, error);
+       MONO_FINISH_BLOCKING;
 
        if (!names) {
                // If there's no array and no error, then return an empty array.
@@ -523,14 +523,14 @@ ves_icall_System_IO_MonoIO_FindClose (gpointer handle)
        IncrementalFind *ifh = handle;
        gint32 error;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        if (FindClose (ifh->find_handle) == FALSE){
                error = GetLastError ();
        } else
                error = ERROR_SUCCESS;
        g_free (ifh->utf8_path);
        g_free (ifh);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        return error;
 }
@@ -591,7 +591,7 @@ ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest,
                                     gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
 
@@ -600,7 +600,7 @@ ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -612,7 +612,7 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
        gboolean ret;
        gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
        guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        if (sourceFileName)
                utf16_sourceFileName = mono_string_chars (sourceFileName);
@@ -631,7 +631,7 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
        if (ret == FALSE)
                *error = GetLastError ();
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return ret;
 }
 
@@ -640,7 +640,7 @@ ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
                                     MonoBoolean overwrite, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -649,7 +649,7 @@ ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -657,7 +657,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -666,7 +666,7 @@ ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -674,7 +674,7 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
 {
        gint32 ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -691,7 +691,7 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -700,7 +700,7 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
                                              gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -710,7 +710,7 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -718,7 +718,7 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -730,7 +730,7 @@ ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -740,7 +740,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
 {
        gboolean result;
        WIN32_FILE_ATTRIBUTE_DATA data;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -753,7 +753,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
                memset (stat, 0, sizeof (MonoIOStat));
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return result;
 }
 
@@ -765,7 +765,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
        HANDLE ret;
        int attributes, attrs;
        gunichar2 *chars;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        chars = mono_string_chars (filename);   
        *error=ERROR_SUCCESS;
@@ -810,7 +810,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
                *error=GetLastError ();
        } 
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -818,7 +818,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -827,7 +827,7 @@ ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -851,9 +851,9 @@ ves_icall_System_IO_MonoIO_Read (HANDLE handle, MonoArray *dest,
 
        buffer = mono_array_addr (dest, guchar, dest_offset);
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        result = ReadFile (handle, buffer, count, &n, NULL);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (!result) {
                *error=GetLastError ();
@@ -882,9 +882,9 @@ ves_icall_System_IO_MonoIO_Write (HANDLE handle, MonoArray *src,
        }
        
        buffer = mono_array_addr (src, guchar, src_offset);
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        result = WriteFile (handle, buffer, count, &n, NULL);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (!result) {
                *error=GetLastError ();
@@ -899,7 +899,7 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                                 gint32 *error)
 {
        gint32 offset_hi;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -911,7 +911,7 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return offset | ((gint64)offset_hi << 32);
 }
 
@@ -919,7 +919,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -928,7 +928,7 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -937,7 +937,7 @@ ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
 {
        gint64 length;
        guint32 length_hi;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -946,7 +946,7 @@ ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return length | ((gint64)length_hi << 32);
 }
 
@@ -1008,7 +1008,7 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
        const FILETIME *creation_filetime;
        const FILETIME *last_access_filetime;
        const FILETIME *last_write_filetime;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -1032,7 +1032,7 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
                *error=GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -1065,9 +1065,9 @@ ves_icall_System_IO_MonoIO_CreatePipe (HANDLE *read_handle,
        attr.bInheritHandle=TRUE;
        attr.lpSecurityDescriptor=NULL;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret=CreatePipe (read_handle, write_handle, &attr, 0);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==FALSE) {
                /* FIXME: throw an exception? */
@@ -1084,9 +1084,9 @@ MonoBoolean ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_ha
        /* This is only used on Windows */
        gboolean ret;
        
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==FALSE) {
                /* FIXME: throw an exception? */
@@ -1177,43 +1177,11 @@ ves_icall_System_IO_MonoIO_get_InvalidPathChars ()
        return chars;
 }
 
-gint32
-ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name)
-{
-       gunichar2 *name;
-       int ret;
-
-       MONO_PREPARE_BLOCKING
-       name=g_new0 (gunichar2, 256);
-       
-       ret=GetTempPath (256, name);
-       if(ret>255) {
-               /* Buffer was too short. Try again... */
-               g_free (name);
-               name=g_new0 (gunichar2, ret+2); /* include the terminator */
-               ret=GetTempPath (ret, name);
-       }
-       MONO_FINISH_BLOCKING
-       
-       if(ret>0) {
-#ifdef DEBUG
-               g_message ("%s: Temp path is [%s] (len %d)", __func__, name, ret);
-#endif
-
-               mono_gc_wbarrier_generic_store ((gpointer) mono_name,
-                               (MonoObject*) mono_string_new_utf16 (mono_domain_get (), name, ret));
-       }
-
-       g_free (name);
-       
-       return(ret);
-}
-
 void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                                      gint64 length, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -1223,14 +1191,14 @@ void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                *error = GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 }
 
 void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
                                        gint64 length, gint32 *error)
 {
        gboolean ret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -1240,7 +1208,7 @@ void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
                *error = GetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 }
 
 //Support for io-layer free mmap'd files.
@@ -1254,7 +1222,7 @@ mono_filesize_from_path (MonoString *string)
        gint64 res;
        char *path = mono_string_to_utf8 (string);
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        if (stat (path, &buf) == -1)
                res = -1;
        else
@@ -1262,7 +1230,7 @@ mono_filesize_from_path (MonoString *string)
 
        g_free (path);
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        return res;
 }
 
@@ -1272,9 +1240,9 @@ mono_filesize_from_fd (int fd)
        struct stat buf;
        int res;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        res = fstat (fd, &buf);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        
        if (res == -1)
                return (gint64)-1;
index fc7f9e1231b4b0fd41df143c8b887a0930ab22fc..564bca32711733eee1cd25bd7cde804a40d40740 100644 (file)
@@ -238,9 +238,6 @@ ves_icall_System_IO_MonoIO_get_PathSeparator (void);
 extern MonoArray *
 ves_icall_System_IO_MonoIO_get_InvalidPathChars (void);
 
-extern gint32
-ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name);
-
 extern void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                                             gint64 length, gint32 *error);
 extern void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
index 108540654798a3e2051a3200840ab07264ab8ee5..def11d9856d8be929b37c1fc92f0c48651ca4dd4 100644 (file)
 #include <config.h>
 #endif
 
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_EVENT_H
+#include <sys/event.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/filewatcher.h>
@@ -189,3 +199,54 @@ ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
 }
 #endif
 
+#if HAVE_KQUEUE
+
+static void
+interrupt_kevent (gpointer data)
+{
+       int *kq_ptr = data;
+
+       /* Interrupt the kevent () call by closing the fd */
+       close (*kq_ptr);
+       /* Signal to managed code that the fd is closed */
+       *kq_ptr = -1;
+}
+
+/*
+ * ves_icall_System_IO_KqueueMonitor_kevent_notimeout:
+ *
+ *   Call kevent (), while handling runtime interruptions.
+ */
+int
+ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer changelist, int nchanges, gpointer eventlist, int nevents)
+{
+       int res;
+       gboolean interrupted;
+
+       mono_thread_info_install_interrupt (interrupt_kevent, kq_ptr, &interrupted);
+       if (interrupted) {
+               close (*kq_ptr);
+               *kq_ptr = -1;
+               return -1;
+       }
+
+       MONO_PREPARE_BLOCKING;
+       res = kevent (*kq_ptr, changelist, nchanges, eventlist, nevents, NULL);
+       MONO_FINISH_BLOCKING;
+
+       mono_thread_info_uninstall_interrupt (&interrupted);
+
+       return res;
+}
+
+#else
+
+int
+ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer changelist, int nchanges, gpointer eventlist, int nevents)
+{
+       g_assert_not_reached ();
+       return -1;
+}
+
+#endif /* #if HAVE_KQUEUE */
+
index c57be128325b0e1f203cdaf325177806779463d3..605fd0e9ac2503d70c8eb2051e4bf7043adf4846 100644 (file)
@@ -32,6 +32,8 @@ int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance (void);
 int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *directory, gint32 mask);
 int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor);
 
+int ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq, gpointer changelist, int nchanges, gpointer eventlist, int nevents);
+
 G_END_DECLS
 
 #endif
index 4bcdfd55e0dce63229d6c0eadef5285cdf7962f2..ff442e43f6a7faf3484ec2848e7d0bc01d0f6438 100644 (file)
@@ -27,4 +27,4 @@
 GCStats gc_stats = {};
 #else
 GCStats gc_stats;
-#endif
\ No newline at end of file
+#endif
index cdc91abedac0a91e9c53bf7cc837fcda806e402f..5bef0b7b31ba167e4c229da5cb5a0577d66aaf77 100644 (file)
@@ -82,9 +82,9 @@ guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
 {
        guint32 result;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        result = WaitForSingleObjectEx (handle, timeout, alertable);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        return result;
 }
@@ -120,6 +120,9 @@ mono_gc_run_finalize (void *obj, void *data)
        MonoDomain *domain;
        RuntimeInvokeFunction runtime_invoke;
 
+       // This function is called from the innards of the GC, so our best alternative for now is to do polling here
+       MONO_SUSPEND_CHECK ();
+
        o = (MonoObject*)((char*)obj + GPOINTER_TO_UINT (data));
 
        if (log_finalizers)
@@ -317,8 +320,11 @@ object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*))
         * end up running them while or after the domain is being cleared, so
         * the objects will not be valid anymore.
         */
-       if (!mono_domain_is_unloading (domain))
+       if (!mono_domain_is_unloading (domain)) {
+               MONO_TRY_BLOCKING;
                mono_gc_register_for_finalization (obj, callback);
+               MONO_FINISH_TRY_BLOCKING;
+       }
 #endif
 }
 
@@ -623,7 +629,12 @@ static HandleData gc_handles [] = {
        {NULL, NULL, 0, HANDLE_PINNED, 0}
 };
 
-#define lock_handles(handles) mono_mutex_lock (&handle_section)
+#define lock_handles(handles) do {     \
+       MONO_TRY_BLOCKING;      \
+       mono_mutex_lock (&handle_section);      \
+       MONO_FINISH_TRY_BLOCKING;       \
+} while (0)
+
 #define unlock_handles(handles) mono_mutex_unlock (&handle_section)
 
 static int
@@ -1088,7 +1099,7 @@ finalizer_thread (gpointer unused)
 
                g_assert (mono_domain_get () == mono_get_root_domain ());
                mono_gc_set_skip_thread (TRUE);
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
 
                if (wait) {
                /* An alertable wait is required so this thread can be suspended on windows */
@@ -1099,7 +1110,7 @@ finalizer_thread (gpointer unused)
 #endif
                }
                wait = TRUE;
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
                mono_gc_set_skip_thread (FALSE);
 
                mono_threads_perform_thread_dump ();
index 677769c97e54d7930a40f7071b20d2b16412ae1d..d84494b65cb12d895a4d53bdad99baa843a0a78e 100644 (file)
@@ -306,6 +306,9 @@ 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)
 
+ICALL_TYPE(KQUEM, "System.IO.KqueueMonitor", KQUEM_1)
+ICALL(KQUEM_1, "kevent_notimeout", ves_icall_System_IO_KqueueMonitor_kevent_notimeout)
+
 ICALL_TYPE(MMAPIMPL, "System.IO.MemoryMappedFiles.MemoryMapImpl", MMAPIMPL_1)
 ICALL(MMAPIMPL_1, "CloseMapping", mono_mmap_close)
 ICALL(MMAPIMPL_2, "ConfigureHandleInheritability", mono_mmap_configure_inheritability)
@@ -335,7 +338,6 @@ ICALL(MONOIO_10, "GetFileSystemEntries", ves_icall_System_IO_MonoIO_GetFileSyste
 ICALL(MONOIO_11, "GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType)
 ICALL(MONOIO_12, "GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength)
 #ifndef PLATFORM_RO_FS
-ICALL(MONOIO_13, "GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath)
 ICALL(MONOIO_14, "Lock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Lock)
 ICALL(MONOIO_15, "MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile)
 #endif /* !PLATFORM_RO_FS */
@@ -366,11 +368,14 @@ ICALL(MONOIO_33, "get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_Volum
 ICALL_TYPE(IOPATH, "System.IO.Path", IOPATH_1)
 ICALL(IOPATH_1, "get_temp_path", ves_icall_System_IO_get_temp_path)
 
-ICALL_TYPE(MATH, "System.Math", MATH_1)
+ICALL_TYPE(MATH, "System.Math", MATH_19)
+ICALL(MATH_19, "Abs(double)", ves_icall_System_Math_Abs_double)
+ICALL(MATH_20, "Abs(single)", ves_icall_System_Math_Abs_single)
 ICALL(MATH_1, "Acos", ves_icall_System_Math_Acos)
 ICALL(MATH_2, "Asin", ves_icall_System_Math_Asin)
 ICALL(MATH_3, "Atan", ves_icall_System_Math_Atan)
 ICALL(MATH_4, "Atan2", ves_icall_System_Math_Atan2)
+ICALL(MATH_21, "Ceiling", ves_icall_System_Math_Ceiling)
 ICALL(MATH_5, "Cos", ves_icall_System_Math_Cos)
 ICALL(MATH_6, "Cosh", ves_icall_System_Math_Cosh)
 ICALL(MATH_7, "Exp", ves_icall_System_Math_Exp)
@@ -379,9 +384,9 @@ ICALL(MATH_9, "Log", ves_icall_System_Math_Log)
 ICALL(MATH_10, "Log10", ves_icall_System_Math_Log10)
 ICALL(MATH_11, "Pow", ves_icall_System_Math_Pow)
 ICALL(MATH_12, "Round", ves_icall_System_Math_Round)
-ICALL(MATH_13, "Round2", ves_icall_System_Math_Round2)
 ICALL(MATH_14, "Sin", ves_icall_System_Math_Sin)
 ICALL(MATH_15, "Sinh", ves_icall_System_Math_Sinh)
+ICALL(MATH_22, "SplitFractionDouble", ves_icall_System_Math_SplitFractionDouble)
 ICALL(MATH_16, "Sqrt", ves_icall_System_Math_Sqrt)
 ICALL(MATH_17, "Tan", ves_icall_System_Math_Tan)
 ICALL(MATH_18, "Tanh", ves_icall_System_Math_Tanh)
@@ -873,6 +878,7 @@ ICALL(MONIT_4, "Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_
 ICALL(MONIT_5, "Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised)
 ICALL(MONIT_6, "Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter)
 ICALL(MONIT_7, "Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait)
+ICALL(MONIT_10, "enter_with_atomic_var", mono_monitor_enter_v4)
 ICALL(MONIT_9, "try_enter_with_atomic_var", ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var)
 
 ICALL_TYPE(MUTEX, "System.Threading.Mutex", MUTEX_1)
index 2d891f3fbfc0fc1342dcd6ccc2f8b0ee7ab571fc..0212a3c909d1d89fc6150ef9e9ff47f99bdf5dbe 100644 (file)
@@ -1924,28 +1924,30 @@ typedef enum {
 } PInfo;
 
 ICALL_EXPORT void
-ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
+ves_icall_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
 {
        MonoDomain *domain = mono_object_domain (property); 
+       const MonoProperty *pproperty = property->property;
 
        if ((req_info & PInfo_ReflectedType) != 0)
                MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
        if ((req_info & PInfo_DeclaringType) != 0)
-               MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &property->property->parent->byval_arg));
+               MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &pproperty->parent->byval_arg));
 
        if ((req_info & PInfo_Name) != 0)
-               MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
+               MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
 
        if ((req_info & PInfo_Attributes) != 0)
-               info->attrs = property->property->attrs;
+               info->attrs = pproperty->attrs;
 
        if ((req_info & PInfo_GetMethod) != 0)
-               MONO_STRUCT_SETREF (info, get, property->property->get ?
-                                                       mono_method_get_object (domain, property->property->get, property->klass): NULL);
-       
+               MONO_STRUCT_SETREF (info, get, pproperty->get &&
+                                                       (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) || pproperty->get->klass == property->klass) ?
+                                                       mono_method_get_object (domain, pproperty->get, property->klass): NULL);
        if ((req_info & PInfo_SetMethod) != 0)
-               MONO_STRUCT_SETREF (info, set, property->property->set ?
-                                                       mono_method_get_object (domain, property->property->set, property->klass): NULL);
+               MONO_STRUCT_SETREF (info, set, pproperty->set &&
+                                                       (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) || pproperty->set->klass == property->klass) ?
+                                                       mono_method_get_object (domain, pproperty->set, property->klass): NULL);
        /* 
         * There may be other methods defined for properties, though, it seems they are not exposed 
         * in the reflection API 
@@ -5681,6 +5683,13 @@ ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, Mo
 {
        guint8 *src_buf, *dest_buf;
 
+       if (count < 0) {
+               mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
+               return FALSE;
+       }
+
+       g_assert (count >= 0);
+
        /* This is called directly from the class libraries without going through the managed wrapper */
        MONO_CHECK_ARG_NULL (src, FALSE);
        MONO_CHECK_ARG_NULL (dest, FALSE);
index d28ea9627063e3f301f4c744e5549af0277dbb9f..ec0e05cfecf8e5941c423c5f363d8c2653dc8c21 100644 (file)
@@ -679,7 +679,7 @@ mono_image_init (MonoImage *image)
                                       g_direct_hash,
                                       class_key_extract,
                                       class_next_value);
-       image->field_cache = mono_conc_hashtable_new (&image->lock, NULL, NULL);
+       image->field_cache = mono_conc_hashtable_new (NULL, NULL);
 
        image->typespec_cache = g_hash_table_new (NULL, NULL);
        image->memberref_signatures = g_hash_table_new (NULL, NULL);
index d9ae9d6fde02568d9854d795c587b31ca8c8043c..0db6ff561fb9bc5f6298081dc9510d2bb94a9ecf 100644 (file)
@@ -600,8 +600,11 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk
                }
        }
 
-       if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container)
+       if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container) {
+               mono_image_lock (image);
                mono_conc_hashtable_insert (image->field_cache, GUINT_TO_POINTER (token), field);
+               mono_image_unlock (image);
+       }
 
        mono_loader_assert_no_error ();
        return field;
@@ -2376,10 +2379,11 @@ stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
        switch (frame->type) {
        case FRAME_TYPE_DEBUGGER_INVOKE:
        case FRAME_TYPE_MANAGED_TO_NATIVE:
+       case FRAME_TYPE_TRAMPOLINE:
                return FALSE;
        case FRAME_TYPE_MANAGED:
                g_assert (frame->ji);
-               return d->func (mono_jit_info_get_method (frame->ji), frame->native_offset, frame->il_offset, frame->managed, d->user_data);
+               return d->func (frame->actual_method, frame->native_offset, frame->il_offset, frame->managed, d->user_data);
                break;
        default:
                g_assert_not_reached ();
@@ -2415,14 +2419,16 @@ async_stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer
        switch (frame->type) {
        case FRAME_TYPE_DEBUGGER_INVOKE:
        case FRAME_TYPE_MANAGED_TO_NATIVE:
+       case FRAME_TYPE_TRAMPOLINE:
                return FALSE;
        case FRAME_TYPE_MANAGED:
                if (!frame->ji)
                        return FALSE;
-               if (frame->ji->async)
+               if (frame->ji->async) {
                        return d->func (NULL, frame->domain, frame->ji->code_start, frame->native_offset, d->user_data);
-               else
+               } else {
                        return d->func (frame->actual_method, frame->domain, frame->ji->code_start, frame->native_offset, d->user_data);
+               }
                break;
        default:
                g_assert_not_reached ();
@@ -2474,9 +2480,9 @@ static gboolean loader_lock_track_ownership = FALSE;
 void
 mono_loader_lock (void)
 {
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_locks_acquire (&loader_mutex, LoaderLock);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
                
        if (G_UNLIKELY (loader_lock_track_ownership)) {
                mono_native_tls_set_value (loader_lock_nest_id, GUINT_TO_POINTER (GPOINTER_TO_UINT (mono_native_tls_get_value (loader_lock_nest_id)) + 1));
index 959dd36aa3c282a90216973f6402dac5990bb871..e0e6ac96a61053d69735feb81d1cbb5e378e5041 100644 (file)
@@ -109,14 +109,16 @@ static void
 add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock)
 {
        int i = 0;
-       gpointer frames[10];
+       const int no_frames = 6;
+       gpointer frames[no_frames];
+
        char *msg;
        if (!trace_file)
                return;
 
-       memset (frames, 0, sizeof (gpointer));
-       mono_backtrace (frames, 6);
-       for (i = 0; i < 6; ++i)
+       memset (frames, 0, sizeof (gpointer) * no_frames);
+       mono_backtrace (frames, no_frames);
+       for (i = 0; i < no_frames; ++i)
                frames [i] = (gpointer)((size_t)frames[i] - base_address);
 
        /*We only dump 5 frames, which should be more than enough to most analysis.*/
index f31f17c46862ae1b1e649ab4ffa65167d1bf5ce9..4c6ae67820d24b42774f5805cb50cda488060a20 100644 (file)
@@ -244,8 +244,8 @@ mono_marshal_init (void)
 #ifdef USE_COOP_GC
                register_icall (mono_threads_prepare_blocking, "mono_threads_prepare_blocking", "int", FALSE);
                register_icall (mono_threads_finish_blocking, "mono_threads_finish_blocking", "void int", FALSE);
-               register_icall (mono_threads_reset_blocking_start, "mono_threads_reset_blocking_start","int", FALSE);
-               register_icall (mono_threads_reset_blocking_end, "mono_threads_reset_blocking_end","void int", FALSE);
+               register_icall (mono_threads_reset_blocking_start, "mono_threads_reset_blocking_start","int", TRUE);
+               register_icall (mono_threads_reset_blocking_end, "mono_threads_reset_blocking_end","void int", TRUE);
 #endif
        }
 }
@@ -8697,7 +8697,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        MonoMethodBuilder *mb;
        MonoMethod *res;
        GHashTable *cache;
-       int i, pos, this_local, ret_local = 0;
+       int i, pos, pos2, this_local, taken_local, ret_local = 0;
        MonoGenericContext *ctx = NULL;
        MonoMethod *orig_method = NULL;
        MonoGenericContainer *container = NULL;
@@ -8738,6 +8738,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_SYNCHRONIZED);
 
 #ifndef DISABLE_JIT
+       mb->skip_visibility = 1;
        /* result */
        if (!MONO_TYPE_IS_VOID (sig->ret))
                ret_local = mono_mb_add_local (mb, sig->ret);
@@ -8766,6 +8767,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
 #ifndef DISABLE_JIT
        /* this */
        this_local = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
+       taken_local = mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
 
        clause = mono_image_alloc0 (method->klass->image, sizeof (MonoExceptionClause));
        clause->flags = MONO_EXCEPTION_CLAUSE_FINALLY;
@@ -8776,7 +8778,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        if (!enter_method) {
                MonoMethodDesc *desc;
 
-               desc = mono_method_desc_new ("Monitor:Enter", FALSE);
+               desc = mono_method_desc_new ("Monitor:enter_with_atomic_var(object,bool&)", FALSE);
                enter_method = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
                g_assert (enter_method);
                mono_method_desc_free (desc);
@@ -8811,6 +8813,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
 
        /* Call Monitor::Enter() */
        mono_mb_emit_ldloc (mb, this_local);
+       mono_mb_emit_ldloc_addr (mb, taken_local);
        mono_mb_emit_managed_call (mb, enter_method, NULL);
 
        clause->try_offset = mono_mb_get_label (mb);
@@ -8837,9 +8840,12 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        clause->try_len = mono_mb_get_pos (mb) - clause->try_offset;
        clause->handler_offset = mono_mb_get_label (mb);
 
-       /* Call Monitor::Exit() */
+       /* Call Monitor::Exit() if needed */
+       mono_mb_emit_ldloc (mb, taken_local);
+       pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
        mono_mb_emit_ldloc (mb, this_local);
        mono_mb_emit_managed_call (mb, exit_method, NULL);
+       mono_mb_patch_branch (mb, pos2);
        mono_mb_emit_byte (mb, CEE_ENDFINALLY);
 
        clause->handler_len = mono_mb_get_pos (mb) - clause->handler_offset;
@@ -11106,6 +11112,9 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        GHashTable *cache;
        MonoMethod *res;
        int i, param_count, sig_size, pos_leave;
+#ifdef USE_COOP_GC
+       int coop_gc_var;
+#endif
 
        g_assert (method);
 
@@ -11159,11 +11168,23 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        if (!MONO_TYPE_IS_VOID (sig->ret))
                mono_mb_add_local (mb, sig->ret);
 
+#ifdef USE_COOP_GC
+       /* local 4, the local to be used when calling the reset_blocking funcs */
+       /* tons of code hardcode 3 to be the return var */
+       coop_gc_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+#endif
+
        /* clear exception arg */
        mono_mb_emit_ldarg (mb, param_count - 1);
        mono_mb_emit_byte (mb, CEE_LDNULL);
        mono_mb_emit_byte (mb, CEE_STIND_REF);
 
+#ifdef USE_COOP_GC
+       /* FIXME this is technically wrong as the callback itself must be executed in gc unsafe context. */
+       mono_mb_emit_icall (mb, mono_threads_reset_blocking_start);
+       mono_mb_emit_stloc (mb, coop_gc_var);
+#endif
+
        /* try */
        clause = mono_image_alloc0 (image, sizeof (MonoExceptionClause));
        clause->try_offset = mono_mb_get_label (mb);
@@ -11233,6 +11254,12 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
                        mono_mb_emit_op (mb, CEE_BOX, mono_class_from_mono_type (sig->ret));
        }
 
+#ifdef USE_COOP_GC
+       /* XXX merge reset_blocking_end with detach */
+       mono_mb_emit_ldloc (mb, coop_gc_var);
+       mono_mb_emit_icall (mb, mono_threads_reset_blocking_end);
+#endif
+
        mono_mb_emit_byte (mb, CEE_RET);
 #endif
 
@@ -11272,12 +11299,3 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method)
        if (marshal_mutex_initialized)
                mono_marshal_unlock ();
 }
-
-static gboolean
-signature_pointer_pair_matches_signature (gpointer key, gpointer value, gpointer user_data)
-{
-       SignaturePointerPair *pair = (SignaturePointerPair*)key;
-       MonoMethodSignature *sig = (MonoMethodSignature*)user_data;
-
-       return mono_metadata_signature_equal (pair->sig, sig);
-}
index b332bd6e99dbba2aac094e39770a0b244e32774c..f08f7fa0b8998b8dd4cbd9d0f992e98353bef5e2 100644 (file)
@@ -2150,8 +2150,6 @@ inflated_method_equal (gconstpointer a, gconstpointer b)
        const MonoMethodInflated *mb = b;
        if (ma->declaring != mb->declaring)
                return FALSE;
-       if (ma->method.method.is_mb_open != mb->method.method.is_mb_open)
-               return FALSE;
        return mono_metadata_generic_context_equal (&ma->context, &mb->context);
 }
 
@@ -2159,7 +2157,7 @@ static guint
 inflated_method_hash (gconstpointer a)
 {
        const MonoMethodInflated *ma = a;
-       return (mono_metadata_generic_context_hash (&ma->context) ^ mono_aligned_addr_hash (ma->declaring)) + ma->method.method.is_mb_open;
+       return (mono_metadata_generic_context_hash (&ma->context) ^ mono_aligned_addr_hash (ma->declaring));
 }
 
 static gboolean
index 36a42db0bf7d13c23d3969b39cc8195831eb52d3..0d9001be1a05514840d263c456affd595d3765e7 100644 (file)
@@ -64,15 +64,7 @@ enum {
  *
  * Bacon's thin locks have a fast path that doesn't need a lock record
  * for the common case of locking an unlocked or shallow-nested
- * object, but the technique relies on encoding the thread ID in 15
- * bits (to avoid too much per-object space overhead.)  Unfortunately
- * I don't think it's possible to reliably encode a pthread_t into 15
- * bits. (The JVM implementation used seems to have a 15-bit
- * per-thread identifier available.)
- *
- * This implementation then combines Dice's basic lock model with
- * Bacon's simplification of keeping a lock record for the lifetime of
- * an object.
+ * object.
  */
 
 
@@ -91,6 +83,8 @@ static MonoThreadsSync *monitor_freelist;
 static MonitorArray *monitor_allocated;
 static int array_size = 16;
 
+/* MonoThreadsSync status helpers */
+
 static inline guint32
 mon_status_get_owner (guint32 status)
 {
@@ -135,6 +129,122 @@ mon_status_have_waiters (guint32 status)
        return status & ENTRY_COUNT_WAITERS;
 }
 
+/* LockWord helpers */
+
+static inline MonoThreadsSync*
+lock_word_get_inflated_lock (LockWord lw)
+{
+       lw.lock_word &= (~LOCK_WORD_STATUS_MASK);
+       return lw.sync;
+}
+
+static inline gboolean
+lock_word_is_inflated (LockWord lw)
+{
+       return lw.lock_word & LOCK_WORD_INFLATED;
+}
+
+static inline gboolean
+lock_word_has_hash (LockWord lw)
+{
+       return lw.lock_word & LOCK_WORD_HAS_HASH;
+}
+
+static inline LockWord
+lock_word_set_has_hash (LockWord lw)
+{
+       LockWord nlw;
+       nlw.lock_word = lw.lock_word | LOCK_WORD_HAS_HASH;
+       return nlw;
+}
+
+static inline gboolean
+lock_word_is_free (LockWord lw)
+{
+       return !lw.lock_word;
+}
+
+static inline gboolean
+lock_word_is_flat (LockWord lw)
+{
+       /* Return whether the lock is flat or free */
+       return (lw.lock_word & LOCK_WORD_STATUS_MASK) == LOCK_WORD_FLAT;
+}
+
+static inline gint32
+lock_word_get_hash (LockWord lw)
+{
+       return (gint32) (lw.lock_word >> LOCK_WORD_HASH_SHIFT);
+}
+
+static inline gint32
+lock_word_get_nest (LockWord lw)
+{
+       if (lock_word_is_free (lw))
+               return 0;
+       /* Inword nest count starts from 0 */
+       return ((lw.lock_word & LOCK_WORD_NEST_MASK) >> LOCK_WORD_NEST_SHIFT) + 1;
+}
+
+static inline gboolean
+lock_word_is_nested (LockWord lw)
+{
+       return lw.lock_word & LOCK_WORD_NEST_MASK;
+}
+
+static inline gboolean
+lock_word_is_max_nest (LockWord lw)
+{
+       return (lw.lock_word & LOCK_WORD_NEST_MASK) == LOCK_WORD_NEST_MASK;
+}
+
+static inline LockWord
+lock_word_increment_nest (LockWord lw)
+{
+       lw.lock_word += 1 << LOCK_WORD_NEST_SHIFT;
+       return lw;
+}
+
+static inline LockWord
+lock_word_decrement_nest (LockWord lw)
+{
+       lw.lock_word -= 1 << LOCK_WORD_NEST_SHIFT;
+       return lw;
+}
+
+static inline gint32
+lock_word_get_owner (LockWord lw)
+{
+       return lw.lock_word >> LOCK_WORD_OWNER_SHIFT;
+}
+
+static inline LockWord
+lock_word_new_thin_hash (gint32 hash)
+{
+       LockWord lw;
+       lw.lock_word = (guint32)hash;
+       lw.lock_word = (lw.lock_word << LOCK_WORD_HASH_SHIFT) | LOCK_WORD_HAS_HASH;
+       return lw;
+}
+
+static inline LockWord
+lock_word_new_inflated (MonoThreadsSync *mon)
+{
+       LockWord lw;
+       lw.sync = mon;
+       lw.lock_word |= LOCK_WORD_INFLATED;
+       return lw;
+}
+
+static inline LockWord
+lock_word_new_flat (gint32 owner)
+{
+       LockWord lw;
+       lw.lock_word = owner;
+       lw.lock_word <<= LOCK_WORD_OWNER_SHIFT;
+       return lw;
+}
+
 void
 mono_monitor_init (void)
 {
@@ -337,26 +447,107 @@ mon_new (gsize id)
        return new;
 }
 
-/*
- * Format of the lock word:
- * thinhash | fathash | data
- *
- * thinhash is the lower bit: if set data is the shifted hashcode of the object.
- * fathash is another bit: if set the hash code is stored in the MonoThreadsSync
- *   struct pointed to by data
- * if neither bit is set and data is non-NULL, data is a MonoThreadsSync
- */
-typedef union {
-       gsize lock_word;
-       MonoThreadsSync *sync;
-} LockWord;
+static MonoThreadsSync*
+alloc_mon (MonoObject *obj, gint32 id)
+{
+       MonoThreadsSync *mon;
 
-enum {
-       LOCK_WORD_THIN_HASH = 1,
-       LOCK_WORD_FAT_HASH = 1 << 1,
-       LOCK_WORD_BITS_MASK = 0x3,
-       LOCK_WORD_HASH_SHIFT = 2
-};
+       mono_monitor_allocator_lock ();
+       mon = mon_new (id);
+       mono_gc_weak_link_add (&mon->data, obj, TRUE);
+       mono_monitor_allocator_unlock ();
+
+       return mon;
+}
+
+
+static void
+discard_mon (MonoThreadsSync *mon)
+{
+       mono_monitor_allocator_lock ();
+       mono_gc_weak_link_remove (&mon->data, TRUE);
+       mon_finalize (mon);
+       mono_monitor_allocator_unlock ();
+}
+
+static void
+mono_monitor_inflate_owned (MonoObject *obj, int id)
+{
+       MonoThreadsSync *mon;
+       LockWord nlw, old_lw, tmp_lw;
+       guint32 nest;
+
+       old_lw.sync = obj->synchronisation;
+       LOCK_DEBUG (g_message ("%s: (%d) Inflating owned lock object %p; LW = %p", __func__, id, obj, old_lw.sync));
+
+       if (lock_word_is_inflated (old_lw)) {
+               /* Someone else inflated the lock in the meantime */
+               return;
+       }
+
+       mon = alloc_mon (obj, id);
+
+       nest = lock_word_get_nest (old_lw);
+       mon->nest = nest;
+
+       nlw = lock_word_new_inflated (mon);
+
+       mono_memory_write_barrier ();
+       tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync);
+       if (tmp_lw.sync != old_lw.sync) {
+               /* Someone else inflated the lock in the meantime */
+               discard_mon (mon);
+       }
+}
+
+static void
+mono_monitor_inflate (MonoObject *obj)
+{
+       MonoThreadsSync *mon;
+       LockWord nlw, old_lw;
+
+       LOCK_DEBUG (g_message ("%s: (%d) Inflating lock object %p; LW = %p", __func__, mono_thread_info_get_small_id (), obj, obj->synchronisation));
+
+       mon = alloc_mon (obj, 0);
+
+       nlw = lock_word_new_inflated (mon);
+
+       old_lw.sync = obj->synchronisation;
+
+       for (;;) {
+               LockWord tmp_lw;
+
+               if (lock_word_is_inflated (old_lw)) {
+                       break;
+               }
+#ifdef HAVE_MOVING_COLLECTOR
+                else if (lock_word_has_hash (old_lw)) {
+                       mon->hash_code = lock_word_get_hash (old_lw);
+                       mon->status = mon_status_set_owner (mon->status, 0);
+                       nlw = lock_word_set_has_hash (nlw);
+               }
+#endif
+               else if (lock_word_is_free (old_lw)) {
+                       mon->status = mon_status_set_owner (mon->status, 0);
+                       mon->nest = 1;
+               } else {
+                       /* Lock is flat */
+                       mon->status = mon_status_set_owner (mon->status, lock_word_get_owner (old_lw));
+                       mon->nest = lock_word_get_nest (old_lw);
+               }
+               mono_memory_write_barrier ();
+               tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync);
+               if (tmp_lw.sync == old_lw.sync) {
+                       /* Successfully inflated the lock */
+                       return;
+               }
+
+               old_lw.sync = tmp_lw.sync;
+       }
+
+       /* Someone else inflated the lock before us */
+       discard_mon (mon);
+}
 
 #define MONO_OBJECT_ALIGNMENT_SHIFT    3
 
@@ -375,14 +566,15 @@ mono_object_hash (MonoObject* obj)
        if (!obj)
                return 0;
        lw.sync = obj->synchronisation;
-       if (lw.lock_word & LOCK_WORD_THIN_HASH) {
-               /*g_print ("fast thin hash %d for obj %p store\n", (unsigned int)lw.lock_word >> LOCK_WORD_HASH_SHIFT, obj);*/
-               return (unsigned int)lw.lock_word >> LOCK_WORD_HASH_SHIFT;
-       }
-       if (lw.lock_word & LOCK_WORD_FAT_HASH) {
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               /*g_print ("fast fat hash %d for obj %p store\n", lw.sync->hash_code, obj);*/
-               return lw.sync->hash_code;
+
+       LOCK_DEBUG (g_message("%s: (%d) Get hash for object %p; LW = %p", __func__, mono_thread_info_get_small_id (), obj, obj->synchronisation));
+
+       if (lock_word_has_hash (lw)) {
+               if (lock_word_is_inflated (lw)) {
+                       return lock_word_get_inflated_lock (lw)->hash_code;
+               } else {
+                       return lock_word_get_hash (lw);
+               }
        }
        /*
         * while we are inside this function, the GC will keep this object pinned,
@@ -392,31 +584,40 @@ mono_object_hash (MonoObject* obj)
         * with the same value.
         */
        hash = (GPOINTER_TO_UINT (obj) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
+#if SIZEOF_VOID_P == 4
        /* clear the top bits as they can be discarded */
-       hash &= ~(LOCK_WORD_BITS_MASK << 30);
-       /* no hash flags were set, so it must be a MonoThreadsSync pointer if not NULL */
-       if (lw.sync) {
-               lw.sync->hash_code = hash;
-               /*g_print ("storing hash code %d for obj %p in sync %p\n", hash, obj, lw.sync);*/
-               lw.lock_word |= LOCK_WORD_FAT_HASH;
-               /* this is safe since we don't deflate locks */
-               obj->synchronisation = lw.sync;
-       } else {
-               /*g_print ("storing thin hash code %d for obj %p\n", hash, obj);*/
-               lw.lock_word = LOCK_WORD_THIN_HASH | (hash << LOCK_WORD_HASH_SHIFT);
-               if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, NULL) == NULL)
+       hash &= ~(LOCK_WORD_STATUS_MASK << (32 - LOCK_WORD_STATUS_BITS));
+#endif
+       if (lock_word_is_free (lw)) {
+               LockWord old_lw;
+               lw = lock_word_new_thin_hash (hash);
+
+               old_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, NULL);
+               if (old_lw.sync == NULL) {
                        return hash;
-               /*g_print ("failed store\n");*/
-               /* someone set the hash flag or someone inflated the object */
-               lw.sync = obj->synchronisation;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH)
+               }
+
+               if (lock_word_has_hash (old_lw)) {
+                       /* Done by somebody else */
                        return hash;
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               lw.sync->hash_code = hash;
-               lw.lock_word |= LOCK_WORD_FAT_HASH;
-               /* this is safe since we don't deflate locks */
-               obj->synchronisation = lw.sync;
+               }
+                       
+               mono_monitor_inflate (obj);
+               lw.sync = obj->synchronisation;
+       } else if (lock_word_is_flat (lw)) {
+               int id = mono_thread_info_get_small_id ();
+               if (lock_word_get_owner (lw) == id)
+                       mono_monitor_inflate_owned (obj, id);
+               else
+                       mono_monitor_inflate (obj);
+               lw.sync = obj->synchronisation;
        }
+
+       /* At this point, the lock is inflated */
+       lock_word_get_inflated_lock (lw)->hash_code = hash;
+       lw = lock_word_set_has_hash (lw);
+       mono_memory_write_barrier ();
+       obj->synchronisation = lw.sync;
        return hash;
 #else
 /*
@@ -427,6 +628,94 @@ mono_object_hash (MonoObject* obj)
 #endif
 }
 
+static void
+mono_monitor_ensure_owned (LockWord lw, guint32 id)
+{
+       if (lock_word_is_flat (lw)) {
+               if (lock_word_get_owner (lw) == id)
+                       return;
+       } else if (lock_word_is_inflated (lw)) {
+               if (mon_status_get_owner (lock_word_get_inflated_lock (lw)->status) == id)
+                       return;
+       }
+
+       mono_set_pending_exception (mono_get_exception_synchronization_lock ("Object synchronization method was called from an unsynchronized block of code."));
+}
+
+/*
+ * When this function is called it has already been established that the
+ * current thread owns the monitor.
+ */
+static void
+mono_monitor_exit_inflated (MonoObject *obj)
+{
+       LockWord lw;
+       MonoThreadsSync *mon;
+       guint32 nest;
+
+       lw.sync = obj->synchronisation;
+       mon = lock_word_get_inflated_lock (lw);
+
+       nest = mon->nest - 1;
+       if (nest == 0) {
+               guint32 new_status, old_status, tmp_status;
+
+               old_status = mon->status;
+
+               /*
+                * Release lock and do the wakeup stuff. It's possible that
+                * the last blocking thread gave up waiting just before we
+                * release the semaphore resulting in a negative entry count
+                * and a futile wakeup next time there's contention for this
+                * object.
+                */
+               for (;;) {
+                       gboolean have_waiters = mon_status_have_waiters (old_status);
+       
+                       new_status = mon_status_set_owner (old_status, 0);
+                       if (have_waiters)
+                               new_status = mon_status_decrement_entry_count (new_status);
+                       tmp_status = InterlockedCompareExchange ((gint32*)&mon->status, new_status, old_status);
+                       if (tmp_status == old_status) {
+                               if (have_waiters)
+                                       ReleaseSemaphore (mon->entry_sem, 1, NULL);
+                               break;
+                       }
+                       old_status = tmp_status;
+               }
+               LOCK_DEBUG (g_message ("%s: (%d) Object %p is now unlocked", __func__, mono_thread_info_get_small_id (), obj));
+       
+               /* object is now unlocked, leave nest==1 so we don't
+                * need to set it when the lock is reacquired
+                */
+       } else {
+               LOCK_DEBUG (g_message ("%s: (%d) Object %p is now locked %d times", __func__, mono_thread_info_get_small_id (), obj, nest));
+               mon->nest = nest;
+       }
+}
+
+/*
+ * When this function is called it has already been established that the
+ * current thread owns the monitor.
+ */
+static void
+mono_monitor_exit_flat (MonoObject *obj, LockWord old_lw)
+{
+       LockWord new_lw, tmp_lw;
+       if (G_UNLIKELY (lock_word_is_nested (old_lw)))
+               new_lw = lock_word_decrement_nest (old_lw);
+       else
+               new_lw.lock_word = 0;
+
+       tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, new_lw.sync, old_lw.sync);
+       if (old_lw.sync != tmp_lw.sync) {
+               /* Someone inflated the lock in the meantime */
+               mono_monitor_exit_inflated (obj);
+       }
+
+       LOCK_DEBUG (g_message ("%s: (%d) Object %p is now locked %d times; LW = %p", __func__, mono_thread_info_get_small_id (), obj, lock_word_get_nest (new_lw), obj->synchronisation));
+}
+
 static void
 mon_decrement_entry_count (MonoThreadsSync *mon)
 {
@@ -448,10 +737,10 @@ mon_decrement_entry_count (MonoThreadsSync *mon)
  * is requested. In this case it returns -1.
  */ 
 static inline gint32 
-mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_interruption)
+mono_monitor_try_enter_inflated (MonoObject *obj, guint32 ms, gboolean allow_interruption, guint32 id)
 {
+       LockWord lw;
        MonoThreadsSync *mon;
-       gsize id = mono_thread_info_get_small_id ();
        HANDLE sem;
        guint32 then = 0, now, delta;
        guint32 waitms;
@@ -463,96 +752,13 @@ mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_int
        LOCK_DEBUG (g_message("%s: (%d) Trying to lock object %p (%d ms)", __func__, id, obj, ms));
 
        if (G_UNLIKELY (!obj)) {
-               mono_raise_exception (mono_get_exception_argument_null ("obj"));
+               mono_set_pending_exception (mono_get_exception_argument_null ("obj"));
                return FALSE;
        }
 
+       lw.sync = obj->synchronisation;
+       mon = lock_word_get_inflated_lock (lw);
 retry:
-       mon = obj->synchronisation;
-
-       /* If the object has never been locked... */
-       if (G_UNLIKELY (mon == NULL)) {
-               mono_monitor_allocator_lock ();
-               mon = mon_new (id);
-               if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, mon, NULL) == NULL) {
-                       mono_gc_weak_link_add (&mon->data, obj, TRUE);
-                       mono_monitor_allocator_unlock ();
-                       /* Successfully locked */
-                       return 1;
-               } else {
-#ifdef HAVE_MOVING_COLLECTOR
-                       LockWord lw;
-                       lw.sync = obj->synchronisation;
-                       if (lw.lock_word & LOCK_WORD_THIN_HASH) {
-                               MonoThreadsSync *oldlw = lw.sync;
-                               /* move the already calculated hash */
-                               mon->hash_code = lw.lock_word >> LOCK_WORD_HASH_SHIFT;
-                               lw.sync = mon;
-                               lw.lock_word |= LOCK_WORD_FAT_HASH;
-                               if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, oldlw) == oldlw) {
-                                       mono_gc_weak_link_add (&mon->data, obj, TRUE);
-                                       mono_monitor_allocator_unlock ();
-                                       /* Successfully locked */
-                                       return 1;
-                               } else {
-                                       mon_finalize (mon);
-                                       mono_monitor_allocator_unlock ();
-                                       goto retry;
-                               }
-                       } else if (lw.lock_word & LOCK_WORD_FAT_HASH) {
-                               mon_finalize (mon);
-                               mono_monitor_allocator_unlock ();
-                               /* get the old lock without the fat hash bit */
-                               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-                               mon = lw.sync;
-                       } else {
-                               mon_finalize (mon);
-                               mono_monitor_allocator_unlock ();
-                               mon = obj->synchronisation;
-                       }
-#else
-                       mon_finalize (mon);
-                       mono_monitor_allocator_unlock ();
-                       mon = obj->synchronisation;
-#endif
-               }
-       } else {
-#ifdef HAVE_MOVING_COLLECTOR
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH) {
-                       MonoThreadsSync *oldlw = lw.sync;
-                       mono_monitor_allocator_lock ();
-                       mon = mon_new (id);
-                       /* move the already calculated hash */
-                       mon->hash_code = lw.lock_word >> LOCK_WORD_HASH_SHIFT;
-                       lw.sync = mon;
-                       lw.lock_word |= LOCK_WORD_FAT_HASH;
-                       if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, oldlw) == oldlw) {
-                               mono_gc_weak_link_add (&mon->data, obj, TRUE);
-                               mono_monitor_allocator_unlock ();
-                               /* Successfully locked */
-                               return 1;
-                       } else {
-                               mon_finalize (mon);
-                               mono_monitor_allocator_unlock ();
-                               goto retry;
-                       }
-               }
-#endif
-       }
-
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-
-       /* If the object has previously been locked but isn't now... */
-
        /* This case differs from Dice's case 3 because we don't
         * deflate locks or cache unused lock records
         */
@@ -674,9 +880,9 @@ retry_contended:
         * We pass TRUE instead of allow_interruption since we have to check for the
         * StopRequested case below.
         */
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = WaitForSingleObjectEx (mon->entry_sem, waitms, TRUE);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
        
@@ -737,6 +943,65 @@ retry_contended:
        }
 }
 
+/*
+ * If allow_interruption == TRUE, the method will be interrupted if abort or suspend
+ * is requested. In this case it returns -1.
+ */
+static inline gint32
+mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_interruption)
+{
+       LockWord lw;
+       int id = mono_thread_info_get_small_id ();
+
+       LOCK_DEBUG (g_message("%s: (%d) Trying to lock object %p (%d ms)", __func__, id, obj, ms));
+
+       if (G_UNLIKELY (!obj)) {
+               mono_set_pending_exception (mono_get_exception_argument_null ("obj"));
+               return FALSE;
+       }
+
+       lw.sync = obj->synchronisation;
+
+       if (G_LIKELY (lock_word_is_free (lw))) {
+               LockWord nlw = lock_word_new_flat (id);
+               if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, NULL) == NULL) {
+                       return 1;
+               } else {
+                       /* Someone acquired it in the meantime or put a hash */
+                       mono_monitor_inflate (obj);
+                       return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+               }
+       } else if (lock_word_is_inflated (lw)) {
+               return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+       } else if (lock_word_is_flat (lw)) {
+               if (lock_word_get_owner (lw) == id) {
+                       if (lock_word_is_max_nest (lw)) {
+                               mono_monitor_inflate_owned (obj, id);
+                               return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+                       } else {
+                               LockWord nlw, old_lw;
+                               nlw = lock_word_increment_nest (lw);
+                               old_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, lw.sync);
+                               if (old_lw.sync != lw.sync) {
+                                       /* Someone else inflated it in the meantime */
+                                       g_assert (lock_word_is_inflated (old_lw));
+                                       return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+                               }
+                               return 1;
+                       }
+               } else {
+                       mono_monitor_inflate (obj);
+                       return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+               }
+       } else if (lock_word_has_hash (lw)) {
+               mono_monitor_inflate (obj);
+               return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+       }
+
+       g_assert_not_reached ();
+       return -1;
+}
+
 gboolean 
 mono_monitor_enter (MonoObject *obj)
 {
@@ -752,90 +1017,37 @@ mono_monitor_try_enter (MonoObject *obj, guint32 ms)
 void
 mono_monitor_exit (MonoObject *obj)
 {
-       MonoThreadsSync *mon;
-       guint32 nest;
-       guint32 new_status, old_status, tmp_status;
+       LockWord lw;
        
        LOCK_DEBUG (g_message ("%s: (%d) Unlocking %p", __func__, mono_thread_info_get_small_id (), obj));
 
        if (G_UNLIKELY (!obj)) {
-               mono_raise_exception (mono_get_exception_argument_null ("obj"));
+               mono_set_pending_exception (mono_get_exception_argument_null ("obj"));
                return;
        }
 
-       mon = obj->synchronisation;
+       lw.sync = obj->synchronisation;
 
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH)
-                       return;
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-       if (G_UNLIKELY (mon == NULL)) {
-               /* No one ever used Enter. Just ignore the Exit request as MS does */
-               return;
-       }
+       mono_monitor_ensure_owned (lw, mono_thread_info_get_small_id ());
 
-       old_status = mon->status;
-       if (G_UNLIKELY (mon_status_get_owner (old_status) != mono_thread_info_get_small_id ())) {
-               return;
-       }
-       
-       nest = mon->nest - 1;
-       if (nest == 0) {
-               /*
-                * Release lock and do the wakeup stuff. It's possible that
-                * the last blocking thread gave up waiting just before we
-                * release the semaphore resulting in a negative entry count
-                * and a futile wakeup next time there's contention for this
-                * object.
-                */
-               for (;;) {
-                       gboolean have_waiters = mon_status_have_waiters (old_status);
-       
-                       new_status = mon_status_set_owner (old_status, 0);
-                       if (have_waiters)
-                               new_status = mon_status_decrement_entry_count (new_status);
-                       tmp_status = InterlockedCompareExchange ((gint32*)&mon->status, new_status, old_status);
-                       if (tmp_status == old_status) {
-                               if (have_waiters)
-                                       ReleaseSemaphore (mon->entry_sem, 1, NULL);
-                               break;
-                       }
-                       old_status = tmp_status;
-               }
-               LOCK_DEBUG (g_message ("%s: (%d) Object %p is now unlocked", __func__, mono_thread_info_get_small_id (), obj));
-       
-               /* object is now unlocked, leave nest==1 so we don't
-                * need to set it when the lock is reacquired
-                */
-
-       } else {
-               LOCK_DEBUG (g_message ("%s: (%d) Object %p is now locked %d times", __func__, mono_thread_info_get_small_id (), obj, nest));
-               mon->nest = nest;
-       }
+       if (G_UNLIKELY (lock_word_is_inflated (lw)))
+               mono_monitor_exit_inflated (obj);
+       else
+               mono_monitor_exit_flat (obj, lw);
 }
 
 void**
 mono_monitor_get_object_monitor_weak_link (MonoObject *object)
 {
        LockWord lw;
-       MonoThreadsSync *sync = NULL;
 
        lw.sync = object->synchronisation;
-       if (lw.lock_word & LOCK_WORD_FAT_HASH) {
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               sync = lw.sync;
-       } else if (!(lw.lock_word & LOCK_WORD_THIN_HASH)) {
-               sync = lw.sync;
-       }
 
-       if (sync && sync->data)
-               return &sync->data;
+       if (lock_word_is_inflated (lw)) {
+               MonoThreadsSync *mon = lock_word_get_inflated_lock (lw);
+               if (mon->data)
+                       return &mon->data;
+       }
        return NULL;
 }
 
@@ -889,8 +1101,11 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject
 void
 mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken)
 {
-       if (*lock_taken == 1)
-               mono_raise_exception (mono_get_exception_argument ("lockTaken", "lockTaken is already true"));
+
+       if (*lock_taken == 1) {
+               mono_set_pending_exception (mono_get_exception_argument ("lockTaken", "lockTaken is already true"));
+               return;
+       }
 
        ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (obj, INFINITE, lock_taken);
 }
@@ -898,27 +1113,16 @@ mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken)
 gboolean 
 ves_icall_System_Threading_Monitor_Monitor_test_owner (MonoObject *obj)
 {
-       MonoThreadsSync *mon;
-       
+       LockWord lw;
+
        LOCK_DEBUG (g_message ("%s: Testing if %p is owned by thread %d", __func__, obj, mono_thread_info_get_small_id()));
 
-       mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH)
-                       return FALSE;
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-       if (mon == NULL) {
-               return FALSE;
-       }
-       
-       if (mon_status_get_owner (mon->status) == mono_thread_info_get_small_id ()) {
-               return(TRUE);
+       lw.sync = obj->synchronisation;
+
+       if (lock_word_is_flat (lw)) {
+               return lock_word_get_owner (lw) == mono_thread_info_get_small_id ();
+       } else if (lock_word_is_inflated (lw)) {
+               return mon_status_get_owner (lock_word_get_inflated_lock (lw)->status) == mono_thread_info_get_small_id ();
        }
        
        return(FALSE);
@@ -927,29 +1131,18 @@ ves_icall_System_Threading_Monitor_Monitor_test_owner (MonoObject *obj)
 gboolean 
 ves_icall_System_Threading_Monitor_Monitor_test_synchronised (MonoObject *obj)
 {
-       MonoThreadsSync *mon;
+       LockWord lw;
 
        LOCK_DEBUG (g_message("%s: (%d) Testing if %p is owned by any thread", __func__, mono_thread_info_get_small_id (), obj));
-       
-       mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH)
-                       return FALSE;
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-       if (mon == NULL) {
-               return FALSE;
-       }
-       
-       if (mon_status_get_owner (mon->status) != 0) {
-               return TRUE;
+
+       lw.sync = obj->synchronisation;
+
+       if (lock_word_is_flat (lw)) {
+               return !lock_word_is_free (lw);
+       } else if (lock_word_is_inflated (lw)) {
+               return mon_status_get_owner (lock_word_get_inflated_lock (lw)->status) != 0;
        }
-       
+
        return FALSE;
 }
 
@@ -961,34 +1154,26 @@ ves_icall_System_Threading_Monitor_Monitor_test_synchronised (MonoObject *obj)
 void
 ves_icall_System_Threading_Monitor_Monitor_pulse (MonoObject *obj)
 {
+       int id;
+       LockWord lw;
        MonoThreadsSync *mon;
-       
+
        LOCK_DEBUG (g_message ("%s: (%d) Pulsing %p", __func__, mono_thread_info_get_small_id (), obj));
        
-       mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH) {
-                       mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
-                       return;
-               }
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-       if (mon == NULL) {
-               mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
-               return;
-       }
-       if (mon_status_get_owner (mon->status) != mono_thread_info_get_small_id ()) {
-               mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked by this thread"));
+       id = mono_thread_info_get_small_id ();
+       lw.sync = obj->synchronisation;
+
+       mono_monitor_ensure_owned (lw, id);
+
+       if (!lock_word_is_inflated (lw)) {
+               /* No threads waiting. A wait would have inflated the lock */
                return;
        }
 
+       mon = lock_word_get_inflated_lock (lw);
+
        LOCK_DEBUG (g_message ("%s: (%d) %d threads waiting", __func__, mono_thread_info_get_small_id (), g_slist_length (mon->wait_list)));
-       
+
        if (mon->wait_list != NULL) {
                LOCK_DEBUG (g_message ("%s: (%d) signalling and dequeuing handle %p", __func__, mono_thread_info_get_small_id (), mon->wait_list->data));
        
@@ -1000,32 +1185,24 @@ ves_icall_System_Threading_Monitor_Monitor_pulse (MonoObject *obj)
 void
 ves_icall_System_Threading_Monitor_Monitor_pulse_all (MonoObject *obj)
 {
+       int id;
+       LockWord lw;
        MonoThreadsSync *mon;
        
        LOCK_DEBUG (g_message("%s: (%d) Pulsing all %p", __func__, mono_thread_info_get_small_id (), obj));
 
-       mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH) {
-                       mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
-                       return;
-               }
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-       if (mon == NULL) {
-               mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
-               return;
-       }
-       if (mon_status_get_owner (mon->status) != mono_thread_info_get_small_id ()) {
-               mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked by this thread"));
+       id = mono_thread_info_get_small_id ();
+       lw.sync = obj->synchronisation;
+
+       mono_monitor_ensure_owned (lw, id);
+
+       if (!lock_word_is_inflated (lw)) {
+               /* No threads waiting. A wait would have inflated the lock */
                return;
        }
 
+       mon = lock_word_get_inflated_lock (lw);
+
        LOCK_DEBUG (g_message ("%s: (%d) %d threads waiting", __func__, mono_thread_info_get_small_id (), g_slist_length (mon->wait_list)));
 
        while (mon->wait_list != NULL) {
@@ -1039,6 +1216,7 @@ ves_icall_System_Threading_Monitor_Monitor_pulse_all (MonoObject *obj)
 gboolean
 ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
 {
+       LockWord lw;
        MonoThreadsSync *mon;
        HANDLE event;
        guint32 nest;
@@ -1046,31 +1224,21 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
        gboolean success = FALSE;
        gint32 regain;
        MonoInternalThread *thread = mono_thread_internal_current ();
+       int id = mono_thread_info_get_small_id ();
 
        LOCK_DEBUG (g_message ("%s: (%d) Trying to wait for %p with timeout %dms", __func__, mono_thread_info_get_small_id (), obj, ms));
-       
-       mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
-       {
-               LockWord lw;
-               lw.sync = mon;
-               if (lw.lock_word & LOCK_WORD_THIN_HASH) {
-                       mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
-                       return FALSE;
-               }
-               lw.lock_word &= ~LOCK_WORD_BITS_MASK;
-               mon = lw.sync;
-       }
-#endif
-       if (mon == NULL) {
-               mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
-               return FALSE;
-       }
-       if (mon_status_get_owner (mon->status) != mono_thread_info_get_small_id ()) {
-               mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked by this thread"));
-               return FALSE;
+
+       lw.sync = obj->synchronisation;
+
+       mono_monitor_ensure_owned (lw, id);
+
+       if (!lock_word_is_inflated (lw)) {
+               mono_monitor_inflate_owned (obj, id);
+               lw.sync = obj->synchronisation;
        }
 
+       mon = lock_word_get_inflated_lock (lw);
+
        /* Do this WaitSleepJoin check before creating the event handle */
        mono_thread_current_check_pending_interrupt ();
        
@@ -1091,7 +1259,8 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
        /* Save the nest count, and release the lock */
        nest = mon->nest;
        mon->nest = 1;
-       mono_monitor_exit (obj);
+       mono_memory_write_barrier ();
+       mono_monitor_exit_inflated (obj);
 
        LOCK_DEBUG (g_message ("%s: (%d) Unlocked %p lock %p", __func__, mono_thread_info_get_small_id (), obj, mon));
 
@@ -1100,9 +1269,9 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
         * is private to this thread.  Therefore even if the event was
         * signalled before we wait, we still succeed.
         */
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = WaitForSingleObjectEx (event, ms, TRUE);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        /* Reset the thread state fairly early, so we don't have to worry
         * about the monitor error checking
@@ -1123,7 +1292,7 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
 
        /* Regain the lock with the previous nest count */
        do {
-               regain = mono_monitor_try_enter_internal (obj, INFINITE, TRUE);
+               regain = mono_monitor_try_enter_inflated (obj, INFINITE, TRUE, id);
                if (regain == -1) 
                        mono_thread_interruption_checkpoint ();
        } while (regain == -1);
@@ -1145,9 +1314,9 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
                /* Poll the event again, just in case it was signalled
                 * while we were trying to regain the monitor lock
                 */
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                ret = WaitForSingleObjectEx (event, 0, FALSE);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
        }
 
        /* Pulse will have popped our event from the queue if it signalled
index 0a7fe777eaad0dbbb75ecb6c0121f8d72bddb6e1..cc00f2044dc08d8638a7e1b0dfe4b4505ed18db1 100644 (file)
@@ -44,6 +44,62 @@ struct _MonoThreadsSync
        void *data;
 };
 
+/*
+ * Lock word format:
+ *
+ * The least significant bit stores whether a hash for the object is computed
+ * which is stored either in the lock word or in the MonoThreadsSync structure
+ * that the lock word points to.
+ *
+ * The second bit stores whether the lock word is inflated, containing an
+ * address to the MonoThreadsSync structure.
+ *
+ * If both bits are 0, either the lock word is free (entire lock word is 0)
+ * or it is a thin/flat lock.
+ *
+ * 32-bit
+ *            LOCK_WORD_FLAT:    [owner:22 | nest:8 | status:2]
+ *       LOCK_WORD_THIN_HASH:    [hash:30 | status:2]
+ *        LOCK_WORD_INFLATED:    [sync:30 | status:2]
+ *        LOCK_WORD_FAT_HASH:    [sync:30 | status:2]
+ *
+ * 64-bit
+ *            LOCK_WORD_FLAT:    [unused:22 | owner:32 | nest:8 | status:2]
+ *       LOCK_WORD_THIN_HASH:    [hash:62 | status:2]
+ *        LOCK_WORD_INFLATED:    [sync:62 | status:2]
+ *        LOCK_WORD_FAT_HASH:    [sync:62 | status:2]
+ *
+ * In order to save processing time and to have one additional value, the nest
+ * count starts from 0 for the lock word (just valid thread ID in the lock word
+ * means that the thread holds the lock once, although nest is 0).
+ * FIXME Have the same convention on inflated locks
+ */
+
+typedef union {
+#if SIZEOF_REGISTER == 8
+       guint64 lock_word;
+#elif SIZEOF_REGISTER == 4
+       guint32 lock_word;
+#endif
+       MonoThreadsSync *sync;
+} LockWord;
+
+
+enum {
+       LOCK_WORD_FLAT = 0,
+       LOCK_WORD_HAS_HASH = 1,
+       LOCK_WORD_INFLATED = 2,
+
+       LOCK_WORD_STATUS_BITS = 2,
+       LOCK_WORD_NEST_BITS = 8,
+
+       LOCK_WORD_STATUS_MASK = (1 << LOCK_WORD_STATUS_BITS) - 1,
+       LOCK_WORD_NEST_MASK = ((1 << LOCK_WORD_NEST_BITS) - 1) << LOCK_WORD_STATUS_BITS,
+
+       LOCK_WORD_HASH_SHIFT = LOCK_WORD_STATUS_BITS,
+       LOCK_WORD_NEST_SHIFT = LOCK_WORD_STATUS_BITS,
+       LOCK_WORD_OWNER_SHIFT = LOCK_WORD_STATUS_BITS + LOCK_WORD_NEST_BITS
+};
 
 MONO_API void mono_locks_dump (gboolean include_untaken);
 
index c8d7a6a10dbabdff4afc406795de473a1d29cf32..bea26483112d833b2036a638339494f1e1319814 100644 (file)
@@ -31,6 +31,7 @@
 #include <glib.h>
 #include "mono-hash.h"
 #include "metadata/gc-internal.h"
+#include <mono/utils/checked-build.h>
 
 #ifdef HAVE_BOEHM_GC
 #define mg_new0(type,n)  ((type *) GC_MALLOC(sizeof(type) * (n)))
@@ -65,6 +66,9 @@ struct _MonoGHashTable {
        MonoGHashGCType gc_type;
 };
 
+static MonoGHashTable *
+mono_g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func);
+
 #ifdef HAVE_SGEN_GC
 static MonoGCDescriptor table_hash_descr = MONO_GC_DESCRIPTOR_NULL;
 
@@ -144,7 +148,7 @@ mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, Mono
        return hash;
 }
 
-MonoGHashTable *
+static MonoGHashTable *
 mono_g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
 {
        MonoGHashTable *hash;
@@ -165,20 +169,6 @@ mono_g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
        return hash;
 }
 
-MonoGHashTable *
-mono_g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func,
-                           GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
-{
-       MonoGHashTable *hash = mono_g_hash_table_new (hash_func, key_equal_func);
-       if (hash == NULL)
-               return NULL;
-       
-       hash->key_destroy_func = key_destroy_func;
-       hash->value_destroy_func = value_destroy_func;
-       
-       return hash;
-}
-
 typedef struct {
        MonoGHashTable *hash;
        int new_size;
@@ -218,6 +208,8 @@ do_rehash (void *_data)
 static void
 rehash (MonoGHashTable *hash)
 {
+       MONO_REQ_GC_UNSAFE_MODE; //we must run in unsafe mode to make rehash safe
+
        int diff = ABS (hash->last_rehash - hash->in_use);
        RehashData data;
        void *old_table G_GNUC_UNUSED; /* unused on Boehm */
@@ -232,7 +224,12 @@ rehash (MonoGHashTable *hash)
        data.new_size = g_spaced_primes_closest (hash->in_use);
        data.table = mg_new0 (Slot *, data.new_size);
 
+#ifdef USE_COOP_GC
+       /* We cannot be preempted */
+       old_table = do_rehash (&data);
+#else
        old_table = mono_gc_invoke_with_gc_lock (do_rehash, &data);
+#endif
        mg_free (old_table);
 }
 
index 9d382f15476457b2fd7b02a2b3242a927245dc17..970302d84db025307b7de777e9e42166bcc5b019 100644 (file)
@@ -23,9 +23,6 @@ typedef enum {
 typedef struct _MonoGHashTable MonoGHashTable;
 
 MONO_API MonoGHashTable *mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type);
-MONO_API MonoGHashTable *mono_g_hash_table_new      (GHashFunc hash_func, GEqualFunc key_equal_func);
-MONO_API MonoGHashTable *mono_g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func,
-                                                    GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func);
 MONO_API guint    mono_g_hash_table_size            (MonoGHashTable *hash);
 MONO_API gpointer mono_g_hash_table_lookup          (MonoGHashTable *hash, gconstpointer key);
 MONO_API gboolean mono_g_hash_table_lookup_extended (MonoGHashTable *hash, gconstpointer key, gpointer *orig_key, gpointer *value);
index 027d3e1b8a675b4d07ae1c5967789ffe0827ba0d..331969425b391128fffa67b30a2bc0447d996835 100644 (file)
@@ -255,6 +255,8 @@ struct _MonoException {
        MonoObject *_data;
        MonoObject *captured_traces;
        MonoArray  *native_trace_ips;
+       /* Dynamic methods referenced by the stack trace */
+       MonoObject *dynamic_methods;
 };
 
 typedef struct {
@@ -634,10 +636,7 @@ mono_async_result_new          (MonoDomain *domain, HANDLE handle,
                             MonoObject *state, gpointer data, MonoObject *object_data);
 
 MonoObject *
-mono_async_result_invoke    (MonoAsyncResult *ares, MonoObject **exc);
-
-MonoObject *
-ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this_obj);
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares);
 
 MonoWaitHandle *
 mono_wait_handle_new       (MonoDomain *domain, HANDLE handle);
index d729ffaeb8a6adc4247b966fcf9cf4f1a1ceff4f..0a2070ab9db1b299d5c11e61142e64e031d11264 100644 (file)
@@ -42,6 +42,7 @@
 #include <mono/utils/mono-counters.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-memory-model.h>
+#include <mono/utils/checked-build.h>
 #include "cominterop.h"
 
 static void
@@ -64,6 +65,8 @@ static mono_mutex_t ldstr_section;
 void
 mono_runtime_object_init (MonoObject *this)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoMethod *method = NULL;
        MonoClass *klass = this->vtable->klass;
 
@@ -108,17 +111,31 @@ typedef struct
 } TypeInitializationLock;
 
 /* for locking access to type_initialization_hash and blocked_thread_hash */
-#define mono_type_initialization_lock() mono_mutex_lock (&type_initialization_section)
-#define mono_type_initialization_unlock() mono_mutex_unlock (&type_initialization_section)
 static mono_mutex_t type_initialization_section;
 
+static inline void
+mono_type_initialization_lock (void)
+{
+       /* The critical sections protected by this lock in mono_runtime_class_init_full () can block */
+       MONO_PREPARE_BLOCKING;
+       mono_mutex_lock (&type_initialization_section);
+       MONO_FINISH_BLOCKING;
+}
+
+static inline void
+mono_type_initialization_unlock (void)
+{
+       mono_mutex_unlock (&type_initialization_section);
+}
 
 static void
 mono_type_init_lock (TypeInitializationLock *lock)
 {
-       MONO_TRY_BLOCKING
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (&lock->initialization_section);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 }
 
 static void
@@ -151,6 +168,8 @@ static MonoRuntimeCallbacks callbacks;
 void
 mono_thread_set_main (MonoThread *thread)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static gboolean registered = FALSE;
 
        if (!registered) {
@@ -164,6 +183,8 @@ mono_thread_set_main (MonoThread *thread)
 MonoThread*
 mono_thread_get_main (void)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return main_thread;
 }
 
@@ -202,6 +223,8 @@ mono_type_initialization_cleanup (void)
 static MonoException*
 get_type_init_exception_for_vtable (MonoVTable *vtable)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *domain = vtable->domain;
        MonoClass *klass = vtable->klass;
        MonoException *ex;
@@ -240,6 +263,8 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
 void
 mono_runtime_class_init (MonoVTable *vtable)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        mono_runtime_class_init_full (vtable, TRUE);
 }
 
@@ -252,11 +277,18 @@ mono_runtime_class_init (MonoVTable *vtable)
 MonoException *
 mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoException *exc;
        MonoException *exc_to_throw;
        MonoMethod *method = NULL;
        MonoClass *klass;
        gchar *full_name;
+       MonoDomain *domain = vtable->domain;
+       TypeInitializationLock *lock;
+       guint32 tid;
+       int do_initialization = 0;
+       MonoDomain *last_domain = NULL;
 
        if (vtable->initialized)
                return NULL;
@@ -288,143 +320,139 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                }
        }
        method = mono_class_get_cctor (klass);
+       if (!method) {
+               vtable->initialized = 1;
+               return NULL;
+       }
+
+       tid = GetCurrentThreadId ();
+
+       mono_type_initialization_lock ();
+       /* double check... */
+       if (vtable->initialized) {
+               mono_type_initialization_unlock ();
+               return NULL;
+       }
+       if (vtable->init_failed) {
+               mono_type_initialization_unlock ();
 
-       if (method) {
-               MonoDomain *domain = vtable->domain;
-               TypeInitializationLock *lock;
-               guint32 tid = GetCurrentThreadId();
-               int do_initialization = 0;
-               MonoDomain *last_domain = NULL;
+               /* The type initialization already failed once, rethrow the same exception */
+               if (raise_exception)
+                       mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+               return get_type_init_exception_for_vtable (vtable);
+       }
+       lock = g_hash_table_lookup (type_initialization_hash, vtable);
+       if (lock == NULL) {
+               /* This thread will get to do the initialization */
+               if (mono_domain_get () != domain) {
+                       /* Transfer into the target domain */
+                       last_domain = mono_domain_get ();
+                       if (!mono_domain_set (domain, FALSE)) {
+                               vtable->initialized = 1;
+                               mono_type_initialization_unlock ();
+                               if (raise_exception)
+                                       mono_raise_exception (mono_get_exception_appdomain_unloaded ());
+                               return mono_get_exception_appdomain_unloaded ();
+                       }
+               }
+               lock = g_malloc (sizeof(TypeInitializationLock));
+               mono_mutex_init_recursive (&lock->initialization_section);
+               lock->initializing_tid = tid;
+               lock->waiting_count = 1;
+               lock->done = FALSE;
+               /* grab the vtable lock while this thread still owns type_initialization_section */
+               /* This is why type_initialization_lock needs to enter blocking mode */
+               mono_type_init_lock (lock);
+               g_hash_table_insert (type_initialization_hash, vtable, lock);
+               do_initialization = 1;
+       } else {
+               gpointer blocked;
+               TypeInitializationLock *pending_lock;
 
-               mono_type_initialization_lock ();
-               /* double check... */
-               if (vtable->initialized) {
+               if (lock->initializing_tid == tid || lock->done) {
                        mono_type_initialization_unlock ();
                        return NULL;
                }
-               if (vtable->init_failed) {
-                       mono_type_initialization_unlock ();
-
-                       /* The type initialization already failed once, rethrow the same exception */
-                       if (raise_exception)
-                               mono_raise_exception (get_type_init_exception_for_vtable (vtable));
-                       return get_type_init_exception_for_vtable (vtable);
-               }                       
-               lock = g_hash_table_lookup (type_initialization_hash, vtable);
-               if (lock == NULL) {
-                       /* This thread will get to do the initialization */
-                       if (mono_domain_get () != domain) {
-                               /* Transfer into the target domain */
-                               last_domain = mono_domain_get ();
-                               if (!mono_domain_set (domain, FALSE)) {
-                                       vtable->initialized = 1;
+               /* see if the thread doing the initialization is already blocked on this thread */
+               blocked = GUINT_TO_POINTER (lock->initializing_tid);
+               while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
+                       if (pending_lock->initializing_tid == tid) {
+                               if (!pending_lock->done) {
                                        mono_type_initialization_unlock ();
-                                       if (raise_exception)
-                                               mono_raise_exception (mono_get_exception_appdomain_unloaded ());
-                                       return mono_get_exception_appdomain_unloaded ();
-                               }
-                       }
-                       lock = g_malloc (sizeof(TypeInitializationLock));
-                       mono_mutex_init_recursive (&lock->initialization_section);
-                       lock->initializing_tid = tid;
-                       lock->waiting_count = 1;
-                       lock->done = FALSE;
-                       /* grab the vtable lock while this thread still owns type_initialization_section */
-                       mono_type_init_lock (lock);
-                       g_hash_table_insert (type_initialization_hash, vtable, lock);
-                       do_initialization = 1;
-               } else {
-                       gpointer blocked;
-                       TypeInitializationLock *pending_lock;
-
-                       if (lock->initializing_tid == tid || lock->done) {
-                               mono_type_initialization_unlock ();
-                               return NULL;
-                       }
-                       /* see if the thread doing the initialization is already blocked on this thread */
-                       blocked = GUINT_TO_POINTER (lock->initializing_tid);
-                       while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
-                               if (pending_lock->initializing_tid == tid) {
-                                       if (!pending_lock->done) {
-                                               mono_type_initialization_unlock ();
-                                               return NULL;
-                                       } else {
-                                               /* the thread doing the initialization is blocked on this thread,
-                                                  but on a lock that has already been freed. It just hasn't got
-                                                  time to awake */
-                                               break;
-                                       }
+                                       return NULL;
+                               } else {
+                                       /* the thread doing the initialization is blocked on this thread,
+                                          but on a lock that has already been freed. It just hasn't got
+                                          time to awake */
+                                       break;
                                }
-                               blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
                        }
-                       ++lock->waiting_count;
-                       /* record the fact that we are waiting on the initializing thread */
-                       g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+                       blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
                }
-               mono_type_initialization_unlock ();
+               ++lock->waiting_count;
+               /* record the fact that we are waiting on the initializing thread */
+               g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+       }
+       mono_type_initialization_unlock ();
 
-               if (do_initialization) {
-                       mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
+       if (do_initialization) {
+               mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
 
-                       /* If the initialization failed, mark the class as unusable. */
-                       /* Avoid infinite loops */
-                       if (!(exc == NULL ||
-                                 (klass->image == mono_defaults.corlib &&              
-                                  !strcmp (klass->name_space, "System") &&
-                                  !strcmp (klass->name, "TypeInitializationException")))) {
-                               vtable->init_failed = 1;
+               /* If the initialization failed, mark the class as unusable. */
+               /* Avoid infinite loops */
+               if (!(exc == NULL ||
+                         (klass->image == mono_defaults.corlib &&
+                          !strcmp (klass->name_space, "System") &&
+                          !strcmp (klass->name, "TypeInitializationException")))) {
+                       vtable->init_failed = 1;
 
-                               if (klass->name_space && *klass->name_space)
-                                       full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
-                               else
-                                       full_name = g_strdup (klass->name);
-                               exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
-                               g_free (full_name);
-
-                               /* 
-                                * Store the exception object so it could be thrown on subsequent 
-                                * accesses.
-                                */
-                               mono_domain_lock (domain);
-                               if (!domain->type_init_exception_hash)
-                                       domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC);
-                               mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
-                               mono_domain_unlock (domain);
-                       }
+                       if (klass->name_space && *klass->name_space)
+                               full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
+                       else
+                               full_name = g_strdup (klass->name);
+                       exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
+                       g_free (full_name);
 
-                       if (last_domain)
-                               mono_domain_set (last_domain, TRUE);
-                       lock->done = TRUE;
-                       mono_type_init_unlock (lock);
-               } else {
-                       /* this just blocks until the initializing thread is done */
-                       mono_type_init_lock (lock);
-                       mono_type_init_unlock (lock);
+                       /*
+                        * Store the exception object so it could be thrown on subsequent
+                        * accesses.
+                        */
+                       mono_domain_lock (domain);
+                       if (!domain->type_init_exception_hash)
+                               domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC);
+                       mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
+                       mono_domain_unlock (domain);
                }
 
-               mono_type_initialization_lock ();
-               if (lock->initializing_tid != tid)
-                       g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
-               --lock->waiting_count;
-               if (lock->waiting_count == 0) {
-                       mono_mutex_destroy (&lock->initialization_section);
-                       g_hash_table_remove (type_initialization_hash, vtable);
-                       g_free (lock);
-               }
-               mono_memory_barrier ();
-               if (!vtable->init_failed)
-                       vtable->initialized = 1;
-               mono_type_initialization_unlock ();
-
-               if (vtable->init_failed) {
-                       /* Either we were the initializing thread or we waited for the initialization */
-                       if (raise_exception)
-                               mono_raise_exception (get_type_init_exception_for_vtable (vtable));
-                       return get_type_init_exception_for_vtable (vtable);
-               }
+               if (last_domain)
+                       mono_domain_set (last_domain, TRUE);
+               lock->done = TRUE;
+               mono_type_init_unlock (lock);
        } else {
+               /* this just blocks until the initializing thread is done */
+               mono_type_init_lock (lock);
+               mono_type_init_unlock (lock);
+       }
+
+       mono_type_initialization_lock ();
+       if (lock->initializing_tid != tid)
+               g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
+       --lock->waiting_count;
+       if (lock->waiting_count == 0) {
+               mono_mutex_destroy (&lock->initialization_section);
+               g_hash_table_remove (type_initialization_hash, vtable);
+               g_free (lock);
+       }
+       mono_memory_barrier ();
+       if (!vtable->init_failed)
                vtable->initialized = 1;
-               return NULL;
+       mono_type_initialization_unlock ();
+
+       if (vtable->init_failed) {
+               /* Either we were the initializing thread or we waited for the initialization */
+               if (raise_exception)
+                       mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+               return get_type_init_exception_for_vtable (vtable);
        }
        return NULL;
 }
@@ -432,6 +460,8 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
 static
 gboolean release_type_locks (gpointer key, gpointer value, gpointer user)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoVTable *vtable = (MonoVTable*)key;
 
        TypeInitializationLock *lock = (TypeInitializationLock*) value;
@@ -457,6 +487,8 @@ gboolean release_type_locks (gpointer key, gpointer value, gpointer user)
 void
 mono_release_type_locks (MonoInternalThread *thread)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        mono_type_initialization_lock ();
        g_hash_table_foreach_remove (type_initialization_hash, release_type_locks, (gpointer)(gsize)(thread->tid));
        mono_type_initialization_unlock ();
@@ -570,6 +602,8 @@ mono_install_compile_method (MonoCompileFunc func)
 gpointer 
 mono_compile_method (MonoMethod *method)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        if (!default_mono_compile_method) {
                g_error ("compile method called on uninitialized runtime");
                return NULL;
@@ -580,12 +614,16 @@ mono_compile_method (MonoMethod *method)
 gpointer
 mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        return arch_create_jump_trampoline (domain, method, add_sync_wrapper);
 }
 
 gpointer
 mono_runtime_create_delegate_trampoline (MonoClass *klass)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        return arch_create_delegate_trampoline (mono_domain_get (), klass);
 }
 
@@ -620,6 +658,8 @@ mono_install_free_method (MonoFreeMethodFunc func)
 void
 mono_runtime_free_method (MonoDomain *domain, MonoMethod *method)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        if (default_mono_free_method != NULL)
                default_mono_free_method (domain, method);
 
@@ -641,6 +681,8 @@ mono_runtime_free_method (MonoDomain *domain, MonoMethod *method)
 static gsize*
 compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoClassField *field;
        MonoClass *p;
        guint32 pos;
@@ -765,6 +807,8 @@ compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int
 gsize*
 mono_class_compute_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        return compute_class_bitmap (class, bitmap, size, offset, max_set, static_fields);
 }
 
@@ -913,12 +957,15 @@ mono_class_insecure_overlapping (MonoClass *klass)
 MonoString*
 mono_string_alloc (int length)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
        return mono_string_new_size (mono_domain_get (), length);
 }
 
 void
 mono_class_compute_gc_descriptor (MonoClass *class)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int max_set = 0;
        gsize *bitmap;
        gsize default_bitmap [4] = {0};
@@ -989,6 +1036,8 @@ mono_class_compute_gc_descriptor (MonoClass *class)
 static gint32
 field_is_special_static (MonoClass *fklass, MonoClassField *field)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoCustomAttrInfo *ainfo;
        int i;
        ainfo = mono_custom_attrs_from_field (fklass, field);
@@ -1041,6 +1090,8 @@ field_is_special_static (MonoClass *fklass, MonoClassField *field)
 guint32
 mono_method_get_imt_slot (MonoMethod *method)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoMethodSignature *sig;
        int hashes_count;
        guint32 *hashes_start, *hashes;
@@ -1113,6 +1164,8 @@ mono_method_get_imt_slot (MonoMethod *method)
 
 static void
 add_imt_builder_entry (MonoImtBuilderEntry **imt_builder, MonoMethod *method, guint32 *imt_collisions_bitmap, int vtable_slot, int slot_num) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 imt_slot = mono_method_get_imt_slot (method);
        MonoImtBuilderEntry *entry;
 
@@ -1175,6 +1228,8 @@ compare_imt_builder_entries (const void *p1, const void *p2) {
 static int
 imt_emit_ir (MonoImtBuilderEntry **sorted_array, int start, int end, GPtrArray *out_array)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int count = end - start;
        int chunk_start = out_array->len;
        if (count < 4) {
@@ -1206,6 +1261,8 @@ imt_emit_ir (MonoImtBuilderEntry **sorted_array, int start, int end, GPtrArray *
 
 static GPtrArray*
 imt_sort_slot_entries (MonoImtBuilderEntry *entries) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int number_of_entries = entries->children + 1;
        MonoImtBuilderEntry **sorted_array = malloc (sizeof (MonoImtBuilderEntry*) * number_of_entries);
        GPtrArray *result = g_ptr_array_new ();
@@ -1230,6 +1287,8 @@ imt_sort_slot_entries (MonoImtBuilderEntry *entries) {
 static gpointer
 initialize_imt_slot (MonoVTable *vtable, MonoDomain *domain, MonoImtBuilderEntry *imt_builder_entry, gpointer fail_tramp)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (imt_builder_entry != NULL) {
                if (imt_builder_entry->children == 0 && !fail_tramp) {
                        /* No collision, return the vtable slot contents */
@@ -1265,6 +1324,8 @@ get_generic_virtual_entries (MonoDomain *domain, gpointer *vtable_slot);
 static void
 build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces, int slot_num)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int i;
        GSList *list_item;
        guint32 imt_collisions_bitmap = 0;
@@ -1406,6 +1467,8 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
 
 static void
 build_imt (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        build_imt_slots (klass, vt, domain, imt, extra_interfaces, -1);
 }
 
@@ -1423,6 +1486,8 @@ build_imt (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt,
 void
 mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        gpointer *imt = (gpointer*)vtable;
        imt -= MONO_IMT_SIZE;
        g_assert (imt_slot >= 0 && imt_slot < MONO_IMT_SIZE);
@@ -1463,6 +1528,8 @@ mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
 static void
 init_thunk_free_lists (MonoDomain *domain)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (domain->thunk_free_lists)
                return;
        domain->thunk_free_lists = mono_domain_alloc0 (domain, sizeof (gpointer) * NUM_FREE_LISTS);
@@ -1496,6 +1563,8 @@ list_index_for_size (int item_size)
 gpointer
 mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        static gboolean inited = FALSE;
        static int generic_virtual_thunks_size = 0;
 
@@ -1554,6 +1623,8 @@ mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size)
 static void
 invalidate_generic_virtual_thunk (MonoDomain *domain, gpointer code)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 *p = code;
        MonoThunkFreeList *l = (MonoThunkFreeList*)(p - 1);
        gboolean found = FALSE;
@@ -1615,6 +1686,8 @@ typedef struct _GenericVirtualCase {
 static MonoImtBuilderEntry*
 get_generic_virtual_entries (MonoDomain *domain, gpointer *vtable_slot)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        GenericVirtualCase *list;
        MonoImtBuilderEntry *entries;
   
@@ -1664,6 +1737,8 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
                                                                                        gpointer *vtable_slot,
                                                                                        MonoMethod *method, gpointer code)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        static gboolean inited = FALSE;
        static int num_added = 0;
 
@@ -1775,6 +1850,8 @@ mono_class_vtable (MonoDomain *domain, MonoClass *class)
 MonoVTable *
 mono_class_vtable_full (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClassRuntimeInfo *runtime_info;
 
        g_assert (class);
@@ -1803,6 +1880,8 @@ mono_class_vtable_full (MonoDomain *domain, MonoClass *class, gboolean raise_on_
 MonoVTable *
 mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoClassRuntimeInfo *runtime_info;
 
        g_assert (class);
@@ -1816,6 +1895,8 @@ mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class)
 static gpointer*
 alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        size_t alloc_offset;
 
        /*
@@ -1837,6 +1918,8 @@ alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
 static MonoVTable *
 mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoVTable *vt;
        MonoClassRuntimeInfo *runtime_info, *old_info;
        MonoClassField *field;
@@ -2170,6 +2253,8 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
 static MonoVTable *
 mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRemotingTarget target_type)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoError error;
        MonoVTable *vt, *pvt;
        int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
@@ -2327,6 +2412,8 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
 gboolean
 mono_class_field_is_special_static (MonoClassField *field)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
                return FALSE;
        if (mono_field_is_deleted (field))
@@ -2348,6 +2435,8 @@ mono_class_field_is_special_static (MonoClassField *field)
 guint32
 mono_class_field_get_special_static_type (MonoClassField *field)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
                return SPECIAL_STATIC_NONE;
        if (mono_field_is_deleted (field))
@@ -2365,6 +2454,8 @@ mono_class_field_get_special_static_type (MonoClassField *field)
 gboolean
 mono_class_has_special_static_fields (MonoClass *klass)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        MonoClassField *field;
        gpointer iter;
 
@@ -2387,6 +2478,8 @@ mono_class_has_special_static_fields (MonoClass *klass)
 static gpointer*
 create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        gpointer *key;
        int i, j;
        
@@ -2438,6 +2531,8 @@ create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
 static gpointer*
 copy_remote_class_key (MonoDomain *domain, gpointer *key)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        int key_size = (GPOINTER_TO_UINT (key [0]) + 1) * sizeof (gpointer);
        gpointer *mp_key = mono_domain_alloc (domain, key_size);
 
@@ -2458,6 +2553,8 @@ copy_remote_class_key (MonoDomain *domain, gpointer *key)
 MonoRemoteClass*
 mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoError error;
        MonoRemoteClass *rc;
        gpointer* key, *mp_key;
@@ -2516,6 +2613,8 @@ mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_
 static MonoRemoteClass*
 clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass *extra_class)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoRemoteClass *rc;
        gpointer* key, *mp_key;
        
@@ -2566,6 +2665,8 @@ clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass
 gpointer
 mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *rp)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        mono_loader_lock (); /*FIXME mono_class_from_mono_type and mono_class_proxy_vtable take it*/
        mono_domain_lock (domain);
        if (rp->target_domain_id != -1) {
@@ -2606,6 +2707,8 @@ mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mon
 void
 mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoTransparentProxy *tproxy;
        MonoRemoteClass *remote_class;
        gboolean redo_vtable;
@@ -2649,6 +2752,8 @@ mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoCla
 MonoMethod*
 mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass *klass;
        MonoMethod **vtable;
        gboolean is_proxy = FALSE;
@@ -2772,6 +2877,8 @@ static MonoInvokeFunc default_mono_runtime_invoke = dummy_mono_runtime_invoke;
 MonoObject*
 mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *result;
 
        if (mono_runtime_get_no_exec ())
@@ -2841,13 +2948,24 @@ mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **
 gpointer
 mono_method_get_unmanaged_thunk (MonoMethod *method)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+       MONO_REQ_API_ENTRYPOINT;
+
+       gpointer res;
+
+       MONO_PREPARE_RESET_BLOCKING
        method = mono_marshal_get_thunk_invoke_wrapper (method);
-       return mono_compile_method (method);
+       res = mono_compile_method (method);
+       MONO_FINISH_RESET_BLOCKING
+
+       return res;
 }
 
 void
 mono_copy_value (MonoType *type, void *dest, void *value, int deref_pointer)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int t;
        if (type->byref) {
                /* object fields cannot be byref, so we don't need a
@@ -2953,6 +3071,8 @@ handle_enum:
 void
 mono_field_set_value (MonoObject *obj, MonoClassField *field, void *value)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        void *dest;
 
        g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
@@ -2974,6 +3094,8 @@ mono_field_set_value (MonoObject *obj, MonoClassField *field, void *value)
 void
 mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        void *dest;
 
        g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
@@ -3004,6 +3126,8 @@ mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
 void *
 mono_vtable_get_static_field_data (MonoVTable *vt)
 {
+       MONO_REQ_GC_NEUTRAL_MODE
+
        if (!vt->has_static_fields)
                return NULL;
        return vt->vtable [vt->klass->vtable_size];
@@ -3012,6 +3136,8 @@ mono_vtable_get_static_field_data (MonoVTable *vt)
 static guint8*
 mono_field_get_addr (MonoObject *obj, MonoVTable *vt, MonoClassField *field)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        guint8 *src;
 
        if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
@@ -3053,6 +3179,8 @@ mono_field_get_addr (MonoObject *obj, MonoVTable *vt, MonoClassField *field)
 void
 mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        void *src;
 
        g_assert (obj);
@@ -3076,6 +3204,8 @@ mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
 MonoObject *
 mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObject *obj)
 {      
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *o;
        MonoClass *klass;
        MonoVTable *vtable = NULL;
@@ -3204,6 +3334,8 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
 int
 mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const char *blob, void *value)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int retval = 0;
        const char *p = blob;
        mono_metadata_decode_blob_size (p, &p);
@@ -3249,6 +3381,8 @@ mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const
 static void
 get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoTypeEnum def_type;
        const char* data;
        
@@ -3259,6 +3393,8 @@ get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value)
 void
 mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *vt, MonoClassField *field, void *value)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        void *src;
 
        g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
@@ -3297,6 +3433,8 @@ mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *
 void
 mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        mono_field_static_get_value_for_thread (mono_thread_internal_current (), vt, field, value);
 }
 
@@ -3318,6 +3456,8 @@ mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
 void
 mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        default_mono_runtime_invoke (prop->set, obj, params, exc);
 }
 
@@ -3341,6 +3481,8 @@ mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObjec
 MonoObject*
 mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return default_mono_runtime_invoke (prop->get, obj, params, exc);
 }
 
@@ -3361,6 +3503,8 @@ mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObjec
 void
 mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass *param_class = klass->cast_class;
 
        mono_class_setup_fields_locking (klass);
@@ -3391,6 +3535,8 @@ mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
 MonoObject*
 mono_nullable_box (guint8 *buf, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass *param_class = klass->cast_class;
 
        mono_class_setup_fields_locking (klass);
@@ -3420,6 +3566,8 @@ mono_nullable_box (guint8 *buf, MonoClass *klass)
 MonoMethod *
 mono_get_delegate_invoke (MonoClass *klass)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoMethod *im;
 
        /* This is called at runtime, so avoid the slower search in metadata */
@@ -3439,6 +3587,8 @@ mono_get_delegate_invoke (MonoClass *klass)
 MonoMethod *
 mono_get_delegate_begin_invoke (MonoClass *klass)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoMethod *im;
 
        /* This is called at runtime, so avoid the slower search in metadata */
@@ -3458,6 +3608,8 @@ mono_get_delegate_begin_invoke (MonoClass *klass)
 MonoMethod *
 mono_get_delegate_end_invoke (MonoClass *klass)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoMethod *im;
 
        /* This is called at runtime, so avoid the slower search in metadata */
@@ -3484,6 +3636,8 @@ mono_get_delegate_end_invoke (MonoClass *klass)
 MonoObject*
 mono_runtime_delegate_invoke (MonoObject *delegate, void **params, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoMethod *im;
        MonoClass *klass = delegate->vtable->klass;
 
@@ -3505,6 +3659,8 @@ static int num_main_args = 0;
 MonoArray*
 mono_runtime_get_main_args (void)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoArray *res;
        int i;
        MonoDomain *domain = mono_domain_get ();
@@ -3520,6 +3676,8 @@ mono_runtime_get_main_args (void)
 static void
 free_main_args (void)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int i;
 
        for (i = 0; i < num_main_args; ++i)
@@ -3540,6 +3698,8 @@ free_main_args (void)
 int
 mono_runtime_set_main_args (int argc, char* argv[])
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int i;
 
        free_main_args ();
@@ -3579,6 +3739,8 @@ int
 mono_runtime_run_main (MonoMethod *method, int argc, char* argv[],
                       MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int i;
        MonoArray *args = NULL;
        MonoDomain *domain = mono_domain_get ();
@@ -3698,6 +3860,8 @@ serialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
 static MonoObject*
 deserialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *deserialize_method;
 
        void *params [1];
@@ -3725,6 +3889,8 @@ deserialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
 static MonoObject*
 make_transparent_proxy (MonoObject *obj, gboolean *failure, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *get_proxy_method;
 
        MonoDomain *domain = mono_domain_get ();
@@ -3769,6 +3935,8 @@ make_transparent_proxy (MonoObject *obj, gboolean *failure, MonoObject **exc)
 MonoObject*
 mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *deserialized = NULL;
        gboolean failure = FALSE;
 
@@ -3800,6 +3968,8 @@ mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain,
 static MonoObject *
 create_unhandled_exception_eventargs (MonoObject *exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass *klass;
        gpointer args [2];
        MonoMethod *method = NULL;
@@ -3827,6 +3997,8 @@ create_unhandled_exception_eventargs (MonoObject *exc)
 /* Used in mono_unhandled_exception */
 static void
 call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, MonoObject *exc) {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *e = NULL;
        gpointer pa [2];
        MonoDomain *current_domain = mono_domain_get ();
@@ -3916,6 +4088,8 @@ mono_runtime_unhandled_exception_policy_get (void) {
 void
 mono_unhandled_exception (MonoObject *exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *current_domain = mono_domain_get ();
        MonoDomain *root_domain = mono_get_root_domain ();
        MonoClassField *field;
@@ -3985,6 +4159,8 @@ mono_runtime_exec_managed_code (MonoDomain *domain,
 int
 mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *domain;
        gpointer pa [1];
        int rval;
@@ -4116,6 +4292,8 @@ MonoObject*
 mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                           MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoMethodSignature *sig = mono_method_signature (method);
        gpointer *pa = NULL;
        MonoObject *res;
@@ -4293,6 +4471,8 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
 static void
 arith_overflow (void)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        mono_raise_exception (mono_get_exception_overflow ());
 }
 
@@ -4310,6 +4490,8 @@ arith_overflow (void)
 MonoObject *
 mono_object_new (MonoDomain *domain, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoVTable *vtable;
 
        vtable = mono_class_vtable (domain, klass);
@@ -4327,6 +4509,8 @@ mono_object_new (MonoDomain *domain, MonoClass *klass)
 MonoObject *
 mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoVTable *vtable;
 
        vtable = mono_class_vtable (domain, klass);
@@ -4350,6 +4534,8 @@ mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
 MonoObject *
 mono_object_new_specific (MonoVTable *vtable)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *o;
 
        /* check for is_com_object for COM Interop */
@@ -4381,6 +4567,8 @@ mono_object_new_specific (MonoVTable *vtable)
 MonoObject *
 mono_object_new_alloc_specific (MonoVTable *vtable)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
 
        if (G_UNLIKELY (vtable->klass->has_finalize))
@@ -4392,6 +4580,8 @@ mono_object_new_alloc_specific (MonoVTable *vtable)
 MonoObject*
 mono_object_new_fast (MonoVTable *vtable)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
 }
 
@@ -4407,6 +4597,8 @@ mono_object_new_fast (MonoVTable *vtable)
 void*
 mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *pass_size_in_words)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        *pass_size_in_words = FALSE;
 
        if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
@@ -4444,6 +4636,8 @@ mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *p
 MonoObject *
 mono_object_new_from_token  (MonoDomain *domain, MonoImage *image, guint32 token)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoError error;
        MonoClass *class;
 
@@ -4463,6 +4657,8 @@ mono_object_new_from_token  (MonoDomain *domain, MonoImage *image, guint32 token
 MonoObject *
 mono_object_clone (MonoObject *obj)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *o;
        int size = obj->vtable->klass->instance_size;
 
@@ -4489,6 +4685,8 @@ mono_object_clone (MonoObject *obj)
 void
 mono_array_full_copy (MonoArray *src, MonoArray *dest)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        uintptr_t size;
        MonoClass *klass = src->obj.vtable->klass;
 
@@ -4522,6 +4720,8 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest)
 MonoArray*
 mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoArray *o;
        uintptr_t size, i;
        uintptr_t *sizes;
@@ -4580,6 +4780,8 @@ mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
 MonoArray*
 mono_array_clone (MonoArray *array)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_array_clone_in_domain (((MonoObject *)array)->vtable->domain, array);
 }
 
@@ -4605,6 +4807,8 @@ mono_array_clone (MonoArray *array)
 gboolean
 mono_array_calc_byte_len (MonoClass *class, uintptr_t len, uintptr_t *res)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        uintptr_t byte_len;
 
        byte_len = mono_array_element_size (class);
@@ -4633,6 +4837,8 @@ mono_array_calc_byte_len (MonoClass *class, uintptr_t len, uintptr_t *res)
 MonoArray*
 mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        uintptr_t byte_len = 0, len, bounds_size;
        MonoObject *o;
        MonoArray *array;
@@ -4710,6 +4916,8 @@ mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *leng
 MonoArray *
 mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass *ac;
 
        ac = mono_array_class_get (eclass, 1);
@@ -4729,6 +4937,8 @@ mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
 MonoArray *
 mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *o;
        MonoArray *ao;
        uintptr_t byte_len;
@@ -4758,6 +4968,8 @@ mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
 MonoString *
 mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoString *s;
        
        s = mono_string_new_size (domain, len);
@@ -4778,6 +4990,8 @@ mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
 MonoString *
 mono_string_new_utf32 (MonoDomain *domain, const mono_unichar4 *text, gint32 len)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoString *s;
        mono_unichar2 *utf16_output = NULL;
        gint32 utf16_len = 0;
@@ -4811,6 +5025,8 @@ mono_string_new_utf32 (MonoDomain *domain, const mono_unichar4 *text, gint32 len
 MonoString *
 mono_string_new_size (MonoDomain *domain, gint32 len)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoString *s;
        MonoVTable *vtable;
        size_t size;
@@ -4840,6 +5056,8 @@ mono_string_new_size (MonoDomain *domain, gint32 len)
 MonoString*
 mono_string_new_len (MonoDomain *domain, const char *text, guint length)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        GError *error = NULL;
        MonoString *o = NULL;
        guint16 *ut;
@@ -4866,6 +5084,8 @@ mono_string_new_len (MonoDomain *domain, const char *text, guint length)
 MonoString*
 mono_string_new (MonoDomain *domain, const char *text)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
     GError *error = NULL;
     MonoString *o = NULL;
     guint16 *ut;
@@ -4913,6 +5133,8 @@ mono_string_new (MonoDomain *domain, const char *text)
 MonoString*
 mono_string_new_wrapper (const char *text)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *domain = mono_domain_get ();
 
        if (text)
@@ -4931,6 +5153,8 @@ mono_string_new_wrapper (const char *text)
 MonoObject *
 mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *res;
        int size;
        MonoVTable *vtable;
@@ -4989,6 +5213,8 @@ mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
 void
 mono_value_copy (gpointer dest, gpointer src, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        mono_gc_wbarrier_value_copy (dest, src, 1, klass);
 }
 
@@ -5006,6 +5232,8 @@ mono_value_copy (gpointer dest, gpointer src, MonoClass *klass)
 void
 mono_value_copy_array (MonoArray *dest, int dest_idx, gpointer src, int count)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int size = mono_array_element_size (dest->obj.vtable->klass);
        char *d = mono_array_addr_with_size_fast (dest, size, dest_idx);
        g_assert (size == mono_class_value_size (mono_object_class (dest)->element_class, NULL));
@@ -5021,6 +5249,8 @@ mono_value_copy_array (MonoArray *dest, int dest_idx, gpointer src, int count)
 MonoDomain*
 mono_object_get_domain (MonoObject *obj)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_object_domain (obj);
 }
 
@@ -5033,6 +5263,8 @@ mono_object_get_domain (MonoObject *obj)
 MonoClass*
 mono_object_get_class (MonoObject *obj)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_object_class (obj);
 }
 /**
@@ -5044,6 +5276,8 @@ mono_object_get_class (MonoObject *obj)
 guint
 mono_object_get_size (MonoObject* o)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass* klass = mono_object_class (o);
        if (klass == mono_defaults.string_class) {
                return sizeof (MonoString) + 2 * mono_string_length ((MonoString*) o) + 2;
@@ -5073,6 +5307,8 @@ mono_object_get_size (MonoObject* o)
 gpointer
 mono_object_unbox (MonoObject *obj)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        /* add assert for valuetypes? */
        g_assert (obj->vtable->klass->valuetype);
        return ((char*)obj) + sizeof (MonoObject);
@@ -5088,6 +5324,8 @@ mono_object_unbox (MonoObject *obj)
 MonoObject *
 mono_object_isinst (MonoObject *obj, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        if (!klass->inited)
                mono_class_init (klass);
 
@@ -5103,6 +5341,8 @@ mono_object_isinst (MonoObject *obj, MonoClass *klass)
 MonoObject *
 mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoVTable *vt;
 
        if (!obj)
@@ -5166,6 +5406,8 @@ mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
 MonoObject *
 mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        if (!obj) return NULL;
        if (mono_object_isinst_mbyref (obj, klass)) return obj;
                
@@ -5184,6 +5426,8 @@ typedef struct {
 static void
 str_lookup (MonoDomain *domain, gpointer user_data)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        LDStrInfo *info = user_data;
        if (info->res || domain == info->orig_domain)
                return;
@@ -5195,6 +5439,8 @@ str_lookup (MonoDomain *domain, gpointer user_data)
 static MonoString*
 mono_string_get_pinned (MonoString *str)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int size;
        MonoString *news;
        size = sizeof (MonoString) + 2 * (mono_string_length (str) + 1);
@@ -5213,6 +5459,8 @@ mono_string_get_pinned (MonoString *str)
 static MonoString*
 mono_string_is_interned_lookup (MonoString *str, int insert)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoGHashTable *ldstr_table;
        MonoString *s, *res;
        MonoDomain *domain;
@@ -5270,6 +5518,8 @@ mono_string_is_interned_lookup (MonoString *str, int insert)
 MonoString*
 mono_string_is_interned (MonoString *o)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_string_is_interned_lookup (o, FALSE);
 }
 
@@ -5283,6 +5533,8 @@ mono_string_is_interned (MonoString *o)
 MonoString*
 mono_string_intern (MonoString *str)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_string_is_interned_lookup (str, TRUE);
 }
 
@@ -5298,6 +5550,8 @@ mono_string_intern (MonoString *str)
 MonoString*
 mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        if (image->dynamic) {
                MonoString *str = mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
                return str;
@@ -5318,6 +5572,8 @@ mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
 static MonoString*
 mono_ldstr_metadata_sig (MonoDomain *domain, const char* sig)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        const char *str = sig;
        MonoString *o, *interned;
        size_t len2;
@@ -5368,6 +5624,8 @@ mono_ldstr_metadata_sig (MonoDomain *domain, const char* sig)
 char *
 mono_string_to_utf8 (MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoError error;
        char *result = mono_string_to_utf8_checked (s, &error);
        
@@ -5388,6 +5646,8 @@ mono_string_to_utf8 (MonoString *s)
 char *
 mono_string_to_utf8_checked (MonoString *s, MonoError *error)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        long written = 0;
        char *as;
        GError *gerror = NULL;
@@ -5430,6 +5690,8 @@ mono_string_to_utf8_checked (MonoString *s, MonoError *error)
 char *
 mono_string_to_utf8_ignore (MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        long written = 0;
        char *as;
 
@@ -5462,6 +5724,8 @@ mono_string_to_utf8_ignore (MonoString *s)
 char *
 mono_string_to_utf8_image_ignore (MonoImage *image, MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_string_to_utf8_internal (NULL, image, s, TRUE, NULL);
 }
 
@@ -5474,6 +5738,8 @@ mono_string_to_utf8_image_ignore (MonoImage *image, MonoString *s)
 char *
 mono_string_to_utf8_mp_ignore (MonoMemPool *mp, MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_string_to_utf8_internal (mp, NULL, s, TRUE, NULL);
 }
 
@@ -5490,6 +5756,8 @@ mono_string_to_utf8_mp_ignore (MonoMemPool *mp, MonoString *s)
 mono_unichar2*
 mono_string_to_utf16 (MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        char *as;
 
        if (s == NULL)
@@ -5517,6 +5785,8 @@ mono_string_to_utf16 (MonoString *s)
 mono_unichar4*
 mono_string_to_utf32 (MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        mono_unichar4 *utf32_output = NULL; 
        GError *error = NULL;
        glong items_written;
@@ -5543,6 +5813,8 @@ mono_string_to_utf32 (MonoString *s)
 MonoString *
 mono_string_from_utf16 (gunichar2 *data)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *domain = mono_domain_get ();
        int len = 0;
 
@@ -5565,6 +5837,8 @@ mono_string_from_utf16 (gunichar2 *data)
 MonoString *
 mono_string_from_utf32 (mono_unichar4 *data)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoString* result = NULL;
        mono_unichar2 *utf16_output = NULL;
        GError *error = NULL;
@@ -5589,6 +5863,8 @@ mono_string_from_utf32 (mono_unichar4 *data)
 static char *
 mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        char *r;
        char *mp_s;
        int len;
@@ -5626,6 +5902,8 @@ mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s,
 char *
 mono_string_to_utf8_image (MonoImage *image, MonoString *s, MonoError *error)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_string_to_utf8_internal (NULL, image, s, FALSE, error);
 }
 
@@ -5638,6 +5916,8 @@ mono_string_to_utf8_image (MonoImage *image, MonoString *s, MonoError *error)
 char *
 mono_string_to_utf8_mp (MonoMemPool *mp, MonoString *s, MonoError *error)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return mono_string_to_utf8_internal (mp, NULL, s, FALSE, error);
 }
 
@@ -5665,6 +5945,8 @@ mono_get_eh_callbacks (void)
 void
 mono_raise_exception (MonoException *ex) 
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        /*
         * NOTE: Do NOT annotate this function with G_GNUC_NORETURN, since
         * that will cause gcc to omit the function epilog, causing problems when
@@ -5677,6 +5959,8 @@ mono_raise_exception (MonoException *ex)
 void
 mono_raise_exception_with_context (MonoException *ex, MonoContext *ctx) 
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        eh_callbacks.mono_raise_exception_with_ctx (ex, ctx);
 }
 
@@ -5690,6 +5974,8 @@ mono_raise_exception_with_context (MonoException *ex, MonoContext *ctx)
 MonoWaitHandle *
 mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoWaitHandle *res;
        gpointer params [1];
        static MonoMethod *handle_set;
@@ -5709,6 +5995,8 @@ mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
 HANDLE
 mono_wait_handle_get_handle (MonoWaitHandle *handle)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoClassField *f_os_handle;
        static MonoClassField *f_safe_handle;
 
@@ -5732,6 +6020,8 @@ mono_wait_handle_get_handle (MonoWaitHandle *handle)
 static MonoObject*
 mono_runtime_capture_context (MonoDomain *domain)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        RuntimeInvokeFunction runtime_invoke;
 
        if (!domain->capture_context_runtime_invoke || !domain->capture_context_method) {
@@ -5762,6 +6052,8 @@ mono_runtime_capture_context (MonoDomain *domain)
 MonoAsyncResult *
 mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data, MonoObject *object_data)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
        MonoObject *context = mono_runtime_capture_context (domain);
        /* we must capture the execution context from the original thread */
@@ -5783,29 +6075,25 @@ mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpo
 }
 
 MonoObject *
-mono_async_result_invoke (MonoAsyncResult *ares, MonoObject **exc)
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoAsyncCall *ac;
        MonoObject *res;
-       MonoInternalThread *thread;
 
        g_assert (ares);
        g_assert (ares->async_delegate);
 
-       thread = mono_thread_internal_current ();
-
        ac = (MonoAsyncCall*) ares->object_data;
        if (!ac) {
-               res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, exc);
+               res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
        } else {
-               MonoArray *out_args = NULL;
                gpointer wait_event = NULL;
 
                ac->msg->exc = NULL;
-               res = mono_message_invoke (ares->async_delegate, ac->msg, exc, &out_args);
-               MONO_OBJECT_SETREF (ac->msg, exc, *exc);
+               res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args);
                MONO_OBJECT_SETREF (ac, res, res);
-               MONO_OBJECT_SETREF (ac, out_args, out_args);
 
                mono_monitor_enter ((MonoObject*) ares);
                ares->completed = 1;
@@ -5816,32 +6104,26 @@ mono_async_result_invoke (MonoAsyncResult *ares, MonoObject **exc)
                if (wait_event != NULL)
                        SetEvent (wait_event);
 
-               if (!ac->cb_method) {
-                       *exc = NULL;
-               } else {
-                       mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, exc);
+               if (ac->cb_method) {
+                       /* we swallow the excepton as it is the behavior on .NET */
+                       MonoObject *exc = NULL;
+                       mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc);
+                       if (exc)
+                               mono_unhandled_exception (exc);
                }
        }
 
        return res;
 }
 
-MonoObject *
-ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this_obj)
-{
-       MonoObject *exc = NULL;
-       MonoObject *res = mono_async_result_invoke (this_obj, &exc);
-       if (exc)
-               mono_raise_exception ((MonoException*) exc);
-       return res;
-}
-
 void
 mono_message_init (MonoDomain *domain,
                   MonoMethodMessage *this_obj, 
                   MonoReflectionMethod *method,
                   MonoArray *out_args)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoClass *object_array_klass;
        static MonoClass *byte_array_klass;
        static MonoClass *string_array_klass;
@@ -5923,6 +6205,8 @@ MonoObject *
 mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, 
                      MonoObject **exc, MonoArray **out_args)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
        gpointer pa [4];
 
@@ -5947,6 +6231,8 @@ MonoObject *
 mono_message_invoke (MonoObject *target, MonoMethodMessage *msg, 
                     MonoObject **exc, MonoArray **out_args) 
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoClass *object_array_klass;
        MonoDomain *domain; 
        MonoMethod *method;
@@ -5984,8 +6270,7 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
                object_array_klass = klass;
        }
 
-       /* FIXME: GC ensure we insert a write barrier for out_args, maybe in the caller? */
-       *out_args = mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count);
+       mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count));
        *exc = NULL;
 
        ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
@@ -6012,6 +6297,8 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
 MonoString *
 mono_object_to_string (MonoObject *obj, MonoObject **exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *to_string = NULL;
        MonoMethod *method;
        void *target = obj;
@@ -6040,6 +6327,8 @@ mono_object_to_string (MonoObject *obj, MonoObject **exc)
 void
 mono_print_unhandled_exception (MonoObject *exc)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoString * str;
        char *message = (char*)"";
        gboolean free_message = FALSE;
@@ -6106,6 +6395,8 @@ mono_print_unhandled_exception (MonoObject *exc)
 void
 mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDelegate *delegate = (MonoDelegate *)this_obj;
 
        g_assert (this_obj);
@@ -6145,6 +6436,8 @@ mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpoint
 void
 mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *domain = mono_domain_get ();
        MonoJitInfo *ji;
        MonoMethod *method = NULL;
@@ -6177,6 +6470,8 @@ MonoMethodMessage *
 mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *invoke, 
                              MonoDelegate **cb, MonoObject **state)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDomain *domain = mono_domain_get ();
        MonoMethodSignature *sig = mono_method_signature (method);
        MonoMethodMessage *msg;
@@ -6229,6 +6524,8 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *
 void
 mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoMethodSignature *sig = mono_method_signature (method);
        int i, j, type, size, out_len;
        
@@ -6291,6 +6588,8 @@ mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoAr
 gpointer
 mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *getter = NULL;
        MonoDomain *domain = mono_domain_get ();
        MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
@@ -6350,6 +6649,8 @@ mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *
 MonoObject *
 mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *getter = NULL;
        MonoDomain *domain = mono_domain_get ();
        MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
@@ -6416,6 +6717,8 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
 void
 mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *setter = NULL;
        MonoDomain *domain = mono_domain_get ();
        MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
@@ -6473,6 +6776,8 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
 void
 mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        static MonoMethod *setter = NULL;
        MonoDomain *domain = mono_domain_get ();
        MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
@@ -6545,6 +6850,8 @@ mono_get_addr_from_ftnptr (gpointer descr)
 gunichar2 *
 mono_string_chars (MonoString *s)
 {
+       // MONO_REQ_GC_UNSAFE_MODE; //FIXME too much trouble for now
+
        return s->chars;
 }
 
@@ -6557,6 +6864,8 @@ mono_string_chars (MonoString *s)
 int
 mono_string_length (MonoString *s)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return s->length;
 }
 
@@ -6570,6 +6879,8 @@ mono_string_length (MonoString *s)
 uintptr_t
 mono_array_length (MonoArray *array)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return array->max_length;
 }
 
@@ -6584,6 +6895,8 @@ mono_array_length (MonoArray *array)
 char*
 mono_array_addr_with_size (MonoArray *array, int size, uintptr_t idx)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        return ((char*)(array)->vector) + size * idx;
 }
 
index f760b21a7748f94aedbf557c4ab0a27137a78c69..7aef3ad2e6095f3fb203843a5ece7843f2b09339 100644 (file)
@@ -36,6 +36,7 @@ typedef void*    (*MonoCompileFunc)        (MonoMethod *method);
 typedef void       (*MonoMainThreadFunc)    (void* user_data);
 
 #define MONO_OBJECT_SETREF(obj,fieldname,value) do {   \
+               g_assert (sizeof((obj)->fieldname) == sizeof (gpointer*));      \
                mono_gc_wbarrier_set_field ((MonoObject*)(obj), &((obj)->fieldname), (MonoObject*)value);       \
                /*(obj)->fieldname = (value);*/ \
        } while (0)
index b738510c1cc180b9faa9c5765b80be1242264688..d547e867fe6751c94ee5e48f5fd32790b4967f36 100644 (file)
@@ -663,10 +663,7 @@ MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoPr
        } else {
                process_info->process_handle = shellex.hProcess;
                process_info->thread_handle = NULL;
-               /* It appears that there's no way to get the pid from a
-                * process handle before windows xp.  Really.
-                */
-#if defined(HAVE_GETPROCESSID) && !defined(MONO_CROSS_COMPILE)
+#if !defined(MONO_CROSS_COMPILE)
                process_info->pid = GetProcessId (shellex.hProcess);
 #else
                process_info->pid = 0;
@@ -807,14 +804,14 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObjec
 {
        guint32 ret;
        
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        if(ms<0) {
                /* Wait forever */
                ret=WaitForSingleObjectEx (process, INFINITE, TRUE);
        } else {
                ret=WaitForSingleObjectEx (process, ms, TRUE);
        }
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==WAIT_OBJECT_0) {
                return(TRUE);
index 096db3127ae0586e894e39196b9f2b367716450d..a06c29c7c139760f866ddc14509b54f52a948078 100644 (file)
@@ -43,6 +43,7 @@
 #include <mono/metadata/mono-ptr-array.h>
 #include <mono/utils/mono-string.h>
 #include <mono/utils/mono-error-internals.h>
+#include <mono/utils/checked-build.h>
 
 static gboolean is_usertype (MonoReflectionType *ref);
 static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
@@ -223,7 +224,9 @@ mono_reflection_init (void)
 static inline void
 dynamic_image_lock (MonoDynamicImage *image)
 {
+       MONO_TRY_BLOCKING;
        mono_image_lock ((MonoImage*)image);
+       MONO_FINISH_TRY_BLOCKING;
 }
 
 static inline void
@@ -235,6 +238,8 @@ dynamic_image_unlock (MonoDynamicImage *image)
 static void
 register_dyn_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        dynamic_image_lock (assembly);
        mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
        dynamic_image_unlock (assembly);
@@ -243,6 +248,8 @@ register_dyn_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
 static MonoObject*
 lookup_dyn_token (MonoDynamicImage *assembly, guint32 token)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoObject *obj;
 
        dynamic_image_lock (assembly);
@@ -255,6 +262,8 @@ lookup_dyn_token (MonoDynamicImage *assembly, guint32 token)
 static void
 sigbuffer_init (SigBuffer *buf, int size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        buf->buf = g_malloc (size);
        buf->p = buf->buf;
        buf->end = buf->buf + size;
@@ -263,6 +272,8 @@ sigbuffer_init (SigBuffer *buf, int size)
 static void
 sigbuffer_make_room (SigBuffer *buf, int size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (buf->end - buf->p < size) {
                int new_size = buf->end - buf->buf + size + 32;
                char *p = g_realloc (buf->buf, new_size);
@@ -276,6 +287,8 @@ sigbuffer_make_room (SigBuffer *buf, int size)
 static void
 sigbuffer_add_value (SigBuffer *buf, guint32 val)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        sigbuffer_make_room (buf, 6);
        mono_metadata_encode_value (val, buf->p, &buf->p);
 }
@@ -283,6 +296,8 @@ sigbuffer_add_value (SigBuffer *buf, guint32 val)
 static void
 sigbuffer_add_byte (SigBuffer *buf, guint8 val)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        sigbuffer_make_room (buf, 1);
        buf->p [0] = val;
        buf->p++;
@@ -291,6 +306,8 @@ sigbuffer_add_byte (SigBuffer *buf, guint8 val)
 static void
 sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        sigbuffer_make_room (buf, size);
        memcpy (buf->p, p, size);
        buf->p += size;
@@ -299,6 +316,8 @@ sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
 static void
 sigbuffer_free (SigBuffer *buf)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        g_free (buf->buf);
 }
 
@@ -312,6 +331,8 @@ sigbuffer_free (SigBuffer *buf)
 static gpointer
 image_g_malloc (MonoImage *image, guint size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (image)
                return mono_image_alloc (image, size);
        else
@@ -328,6 +349,8 @@ image_g_malloc (MonoImage *image, guint size)
 static gpointer
 image_g_malloc0 (MonoImage *image, guint size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (image)
                return mono_image_alloc0 (image, size);
        else
@@ -338,6 +361,8 @@ image_g_malloc0 (MonoImage *image, guint size)
 static char*
 image_strdup (MonoImage *image, const char *s)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (image)
                return mono_image_strdup (image, s);
        else
@@ -355,6 +380,8 @@ image_strdup (MonoImage *image, const char *s)
 static void
 alloc_table (MonoDynamicTable *table, guint nrows)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        table->rows = nrows;
        g_assert (table->columns);
        if (nrows + 1 >= table->alloc_rows) {
@@ -372,6 +399,8 @@ alloc_table (MonoDynamicTable *table, guint nrows)
 static void
 make_room_in_stream (MonoDynamicStream *stream, int size)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (size <= stream->alloc_size)
                return;
        
@@ -388,6 +417,8 @@ make_room_in_stream (MonoDynamicStream *stream, int size)
 static guint32
 string_heap_insert (MonoDynamicStream *sh, const char *str)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 idx;
        guint32 len;
        gpointer oldkey, oldval;
@@ -414,6 +445,8 @@ string_heap_insert (MonoDynamicStream *sh, const char *str)
 static guint32
 string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        char *name = mono_string_to_utf8 (str);
        guint32 idx;
        idx = string_heap_insert (sh, name);
@@ -425,6 +458,8 @@ string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str)
 static void
 string_heap_init (MonoDynamicStream *sh)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        sh->index = 0;
        sh->alloc_size = 4096;
        sh->data = g_malloc (4096);
@@ -436,6 +471,8 @@ string_heap_init (MonoDynamicStream *sh)
 static guint32
 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 idx;
        
        make_room_in_stream (stream, stream->index + len);
@@ -452,6 +489,8 @@ mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32
 static guint32
 mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 idx;
        
        make_room_in_stream (stream, stream->index + len);
@@ -464,6 +503,8 @@ mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
 static void
 stream_data_align (MonoDynamicStream *stream)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        char buf [4] = {0};
        guint32 count = stream->index % 4;
 
@@ -476,6 +517,8 @@ stream_data_align (MonoDynamicStream *stream)
 static int
 mono_blob_entry_hash (const char* str)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint len, h;
        const char *end;
        len = mono_metadata_decode_blob_size (str, &str);
@@ -492,6 +535,8 @@ mono_blob_entry_hash (const char* str)
 
 static gboolean
 mono_blob_entry_equal (const char *str1, const char *str2) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int len, len2;
        const char *end1;
        const char *end2;
@@ -505,6 +550,8 @@ mono_blob_entry_equal (const char *str1, const char *str2) {
 static guint32
 add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 idx;
        char *copy;
        gpointer oldkey, oldval;
@@ -526,6 +573,8 @@ add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int
 static guint32
 sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        char blob_size [8];
        char *b = blob_size;
        guint32 size = buf->p - buf->buf;
@@ -541,6 +590,7 @@ sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
  */
 static void
 swap_with_size (char *dest, const char* val, int len, int nelem) {
+       MONO_REQ_GC_NEUTRAL_MODE;
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
        int elem;
 
@@ -583,6 +633,8 @@ swap_with_size (char *dest, const char* val, int len, int nelem) {
 static guint32
 add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+       
        char blob_size [64];
        char *b = blob_size;
        guint32 idx = 0, len;
@@ -608,6 +660,8 @@ add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
 static MonoClass *
 default_class_from_mono_type (MonoType *type)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        switch (type->type) {
        case MONO_TYPE_OBJECT:
                return mono_defaults.object_class;
@@ -660,6 +714,8 @@ default_class_from_mono_type (MonoType *type)
 gpointer
 mono_class_get_ref_info (MonoClass *klass)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        if (klass->ref_info_handle == 0)
                return NULL;
        else
@@ -669,6 +725,8 @@ mono_class_get_ref_info (MonoClass *klass)
 void
 mono_class_set_ref_info (MonoClass *klass, gpointer obj)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
        g_assert (klass->ref_info_handle != 0);
 }
@@ -676,6 +734,8 @@ mono_class_set_ref_info (MonoClass *klass, gpointer obj)
 void
 mono_class_free_ref_info (MonoClass *klass)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (klass->ref_info_handle) {
                mono_gchandle_free (klass->ref_info_handle);
                klass->ref_info_handle = 0;
@@ -685,6 +745,8 @@ mono_class_free_ref_info (MonoClass *klass)
 static void
 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int i;
        MonoGenericInst *class_inst;
        MonoClass *klass;
@@ -707,6 +769,8 @@ encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigB
 static void
 encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (!type) {
                g_assert_not_reached ();
                return;
@@ -788,6 +852,8 @@ encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
 static void
 encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, SigBuffer *buf)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        if (!type) {
                sigbuffer_add_value (buf, MONO_TYPE_VOID);
                return;
@@ -799,6 +865,8 @@ encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, Si
 static void
 encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int i;
 
        if (modreq) {
@@ -821,6 +889,8 @@ encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArra
 static guint32
 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        SigBuffer buf;
        int i;
        guint32 nparams =  sig->param_count;
@@ -857,6 +927,8 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
 static guint32
 method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        /*
         * FIXME: reuse code from method_encode_signature().
         */
@@ -912,6 +984,8 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui
 static guint32
 encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint32 idx, sig_idx;
@@ -955,6 +1029,8 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
 static guint32
 method_count_clauses (MonoReflectionILGen *ilgen)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        guint32 num_clauses = 0;
        int i;
 
@@ -974,6 +1050,8 @@ method_count_clauses (MonoReflectionILGen *ilgen)
 static MonoExceptionClause*
 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoExceptionClause *clauses;
        MonoExceptionClause *clause;
        MonoILExceptionInfo *ex_info;
@@ -1023,6 +1101,8 @@ method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflect
 static guint32
 method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        char flags = 0;
        guint32 idx;
        guint32 code_size;
@@ -1178,6 +1258,8 @@ fat_header:
 static guint32
 find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32 token)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        int i;
        MonoDynamicTable *table;
        guint32 *values;
@@ -1201,6 +1283,8 @@ find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32
 static MonoCustomAttrInfo*
 lookup_custom_attr (MonoImage *image, gpointer member)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoCustomAttrInfo* res;
 
        res = mono_image_property_lookup (image, member, MONO_PROP_DYNAMIC_CATTR);
@@ -1216,6 +1300,8 @@ lookup_custom_attr (MonoImage *image, gpointer member)
 static gboolean
 custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        /* FIXME: Need to do more checks */
        if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
                int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
@@ -1230,6 +1316,8 @@ custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
 static MonoCustomAttrInfo*
 mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        int i, index, count, not_visible;
        MonoCustomAttrInfo *ainfo;
        MonoReflectionCustomAttr *cattr;
@@ -1278,6 +1366,8 @@ mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArr
 static void
 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoCustomAttrInfo *ainfo, *tmp;
 
        if (!cattrs || !mono_array_length (cattrs))
@@ -1298,6 +1388,8 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
 void
 mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        if (!ainfo->cached)
                g_free (ainfo);
 }
@@ -1309,6 +1401,8 @@ mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
 static void
 mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        MonoReflectionCustomAttr *cattr;
        guint32 *values;
@@ -1361,6 +1455,8 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo
 static void
 mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint32 count, i, idx;
@@ -1410,6 +1506,8 @@ mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token,
 static void
 mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint i, count;
@@ -1485,6 +1583,8 @@ mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly
 static void
 reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        memset (rmb, 0, sizeof (ReflectionMethodBuilder));
 
        rmb->ilgen = mb->ilgen;
@@ -1524,6 +1624,8 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, Mono
 static void
 reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
 
        memset (rmb, 0, sizeof (ReflectionMethodBuilder));
@@ -1557,6 +1659,8 @@ reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoRe
 static void
 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        memset (rmb, 0, sizeof (ReflectionMethodBuilder));
 
        rmb->ilgen = mb->ilgen;
@@ -1589,6 +1693,8 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, Mono
 static void
 mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
        MonoDynamicTable *table;
        guint32 *values;
@@ -1628,6 +1734,8 @@ mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuild
 static void
 mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        ReflectionMethodBuilder rmb;
@@ -1681,6 +1789,8 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *a
 static void
 mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        ReflectionMethodBuilder rmb;
 
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
@@ -1693,11 +1803,16 @@ mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, Mon
 static char*
 type_get_fully_qualified_name (MonoType *type)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
 }
 
 static char*
-type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
+type_get_qualified_name (MonoType *type, MonoAssembly *ass)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoClass *klass;
        MonoAssembly *ta;
 
@@ -1721,6 +1836,8 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
 static guint32
 fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        SigBuffer buf;
        guint32 idx, i, token;
 
@@ -1761,6 +1878,8 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, M
 static guint32
 field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        SigBuffer buf;
        guint32 idx;
        guint32 typespec = 0;
@@ -1794,7 +1913,10 @@ field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *
 }
 
 static guint32
-encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type) {
+encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
        char blob_size [64];
        char *b = blob_size;
        char *box_val;
@@ -1891,7 +2013,10 @@ handle_enum:
 }
 
 static guint32
-encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
+encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
        char *str;
        SigBuffer buf;
        guint32 idx, len;
@@ -1968,6 +2093,8 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
 static void
 mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
 
@@ -2032,6 +2159,8 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
 static guint32
 property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        SigBuffer buf;
        guint32 nparams = 0;
        MonoReflectionMethodBuilder *mb = fb->get_method;
@@ -2073,6 +2202,8 @@ property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBui
 static void
 mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint num_methods = 0;
@@ -2131,6 +2262,8 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImag
 static void
 mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint num_methods = 0;
@@ -2187,6 +2320,8 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass
 static void
 encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 num_constraints, i;
        guint32 *values;
@@ -2225,6 +2360,8 @@ encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynam
 static void
 mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        GenericParamTableEntry *entry;
 
        /*
@@ -2246,6 +2383,8 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
 static void
 write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        MonoGenericParam *param;
        guint32 *values;
@@ -2270,6 +2409,8 @@ write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *e
 static guint32
 resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 token;
        guint32 *values;
@@ -2340,6 +2481,8 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
 static guint32
 create_typespec (MonoDynamicImage *assembly, MonoType *type)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token;
@@ -2392,6 +2535,8 @@ create_typespec (MonoDynamicImage *assembly, MonoType *type)
 static guint32
 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
 {
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token, scope, enclosing;
@@ -2454,6 +2599,8 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
 static guint32
 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token, pclass;
@@ -2500,6 +2647,8 @@ mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const c
 static guint32
 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 parent = mono_image_typedef_or_ref (assembly, type);
        return mono_image_add_memberef_row (assembly, parent, name, sig);
 }
@@ -2508,6 +2657,8 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons
 static guint32
 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
 {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
        guint32 token;
        MonoMethodSignature *sig;
        
@@ -11738,8 +11889,19 @@ static void
 free_dynamic_method (void *dynamic_method)
 {
        DynamicMethodReleaseData *data = dynamic_method;
+       MonoDomain *domain = data->domain;
+       MonoMethod *method = data->handle;
+       gpointer *dis_link;
+
+       mono_domain_lock (domain);
+       dis_link = g_hash_table_lookup (domain->method_to_dyn_method, method);
+       g_hash_table_remove (domain->method_to_dyn_method, method);
+       mono_domain_unlock (domain);
+       g_assert (dis_link);
+       mono_gc_weak_link_remove (dis_link, TRUE);
+       g_free (dis_link);
 
-       mono_runtime_free_method (data->domain, data->handle);
+       mono_runtime_free_method (domain, method);
        g_free (data);
 }
 
@@ -11752,7 +11914,9 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
        ReflectionMethodBuilder rmb;
        MonoMethodSignature *sig;
        MonoClass *klass;
+       MonoDomain *domain;
        GSList *l;
+       void *dis_link;
        int i;
 
        if (mono_runtime_is_shutting_down ())
@@ -11849,6 +12013,15 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 
        /* ilgen is no longer needed */
        mb->ilgen = NULL;
+
+       domain = mono_domain_get ();
+       mono_domain_lock (domain);
+       if (!domain->method_to_dyn_method)
+               domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
+       dis_link = g_new0 (gpointer, 1);
+       mono_gc_weak_link_add (dis_link, (MonoObject*)mb, TRUE);
+       g_hash_table_insert (domain->method_to_dyn_method, handle, dis_link);
+       mono_domain_unlock (domain);
 }
 
 #endif /* DISABLE_REFLECTION_EMIT */
diff --git a/mono/metadata/sgen-os-coop.c b/mono/metadata/sgen-os-coop.c
new file mode 100644 (file)
index 0000000..165c0d4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * sgen-os-coop.c: SGen Cooperative backend support.
+ *
+ * Author:
+ *     João Matos (joao.matos@xamarin.com)
+ * Copyright (C) 2015 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+#ifdef HAVE_SGEN_GC
+
+
+#include <glib.h>
+#include "sgen/sgen-gc.h"
+#include "sgen/sgen-archdep.h"
+#include "sgen/sgen-protocol.h"
+#include "metadata/object-internals.h"
+#include "metadata/gc-internal.h"
+
+
+#if defined(USE_COOP_GC)
+
+gboolean
+sgen_resume_thread (SgenThreadInfo *info)
+{
+       g_error ("FIXME");
+       return FALSE;
+}
+
+gboolean
+sgen_suspend_thread (SgenThreadInfo *info)
+{
+       g_error ("FIXME");
+       return FALSE;
+}
+
+void
+sgen_wait_for_suspend_ack (int count)
+{
+}
+
+/* LOCKING: assumes the GC lock is held */
+int
+sgen_thread_handshake (BOOL suspend)
+{
+       g_error ("FIXME");
+       return 0;
+}
+
+void
+sgen_os_init (void)
+{
+}
+
+int
+mono_gc_get_suspend_signal (void)
+{
+       return -1;
+}
+
+int
+mono_gc_get_restart_signal (void)
+{
+       return -1;
+}
+
+#endif
+#endif
\ No newline at end of file
index db3297f15d7059d91f7f21ac2cb1d8610cc0e41c..46d30d81c4d664f3386c040356e0e60f2023ae4d 100644 (file)
@@ -137,7 +137,6 @@ sgen_thread_handshake (BOOL suspend)
        } END_FOREACH_THREAD_SAFE
        return count;
 }
-#endif
 
 void
 sgen_os_init (void)
@@ -157,3 +156,4 @@ mono_gc_get_restart_signal (void)
 }
 #endif
 #endif
+#endif
index d0aa841296abca3ffc5e6da7ec0a5080bf7ccacb..a45d6be1d9c44c13c527d31cfa2f4eded804f868 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "config.h"
 
-#ifdef HAVE_SGEN_GC
+#if defined(HAVE_SGEN_GC) && !defined(USE_COOP_GC)
 #if !defined(__MACH__) && !MONO_MACH_ARCH_SUPPORTED && defined(HAVE_PTHREAD_KILL)
 
 #include <errno.h>
index 656d8393045abfc5cf3a4d49365cc6c6f13a686b..3145a5e35353e235923ce95f58075a0f1b7526f5 100644 (file)
@@ -61,25 +61,25 @@ sgen_suspend_thread (SgenThreadInfo *info)
 #ifdef USE_MONO_CTX
        memset (&info->client_info.ctx, 0, sizeof (MonoContext));
 #ifdef TARGET_AMD64
-       info->client_info.ctx.rip = context.Rip;
-       info->client_info.ctx.rax = context.Rax;
-       info->client_info.ctx.rcx = context.Rcx;
-       info->client_info.ctx.rdx = context.Rdx;
-       info->client_info.ctx.rbx = context.Rbx;
-       info->client_info.ctx.rsp = context.Rsp;
-       info->client_info.ctx.rbp = context.Rbp;
-       info->client_info.ctx.rsi = context.Rsi;
-       info->client_info.ctx.rdi = context.Rdi;
-       info->client_info.ctx.r8 = context.R8;
-       info->client_info.ctx.r9 = context.R9;
-       info->client_info.ctx.r10 = context.R10;
-       info->client_info.ctx.r11 = context.R11;
-       info->client_info.ctx.r12 = context.R12;
-       info->client_info.ctx.r13 = context.R13;
-       info->client_info.ctx.r14 = context.R14;
-       info->client_info.ctx.r15 = context.R15;
-       info->client_info.stopped_ip = info->client_info.ctx.rip;
-       info->client_info.stack_start = (char*)info->client_info.ctx.rsp - REDZONE_SIZE;
+    info->client_info.ctx.gregs[AMD64_RIP] = context.Rip;
+    info->client_info.ctx.gregs[AMD64_RAX] = context.Rax;
+    info->client_info.ctx.gregs[AMD64_RCX] = context.Rcx;
+    info->client_info.ctx.gregs[AMD64_RDX] = context.Rdx;
+    info->client_info.ctx.gregs[AMD64_RBX] = context.Rbx;
+    info->client_info.ctx.gregs[AMD64_RSP] = context.Rsp;
+    info->client_info.ctx.gregs[AMD64_RBP] = context.Rbp;
+    info->client_info.ctx.gregs[AMD64_RSI] = context.Rsi;
+    info->client_info.ctx.gregs[AMD64_RDI] = context.Rdi;
+    info->client_info.ctx.gregs[AMD64_R8] = context.R8;
+    info->client_info.ctx.gregs[AMD64_R9] = context.R9;
+    info->client_info.ctx.gregs[AMD64_R10] = context.R10;
+    info->client_info.ctx.gregs[AMD64_R11] = context.R11;
+    info->client_info.ctx.gregs[AMD64_R12] = context.R12;
+    info->client_info.ctx.gregs[AMD64_R13] = context.R13;
+    info->client_info.ctx.gregs[AMD64_R14] = context.R14;
+    info->client_info.ctx.gregs[AMD64_R15] = context.R15;
+    info->client_info.stopped_ip = info->client_info.ctx.gregs[AMD64_RIP];
+    info->client_info.stack_start = (char*)info->client_info.ctx.gregs[AMD64_RSP] - REDZONE_SIZE;
 #else
        info->client_info.ctx.edi = context.Edi;
        info->client_info.ctx.esi = context.Esi;
index caddce127d60d81176fbfc5498913c6c818c7e45..475d8321378203b1ef83c3482f998149b2b6efba 100644 (file)
@@ -773,7 +773,7 @@ gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock,
 {
        SOCKET newsock;
        MonoInternalThread* curthread G_GNUC_UNUSED = mono_thread_internal_current ();
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error = 0;
 #ifdef HOST_WIN32
@@ -785,7 +785,7 @@ gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock,
 #else
        newsock = _wapi_accept (sock, NULL, 0);
 #endif
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(newsock==INVALID_SOCKET) {
                *error = WSAGetLastError ();
@@ -976,9 +976,9 @@ extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SO
                return NULL;
        }
        sa = (salen <= 128) ? alloca (salen) : g_malloc0 (salen);
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_getsockname (sock, (struct sockaddr *)sa, &salen);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
@@ -1011,9 +1011,9 @@ extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(S
        }
        sa = (salen <= 128) ? alloca (salen) : g_malloc0 (salen);
        /* Note: linux returns just 2 for AF_UNIX. Always. */
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_getpeername (sock, (struct sockaddr *)sa, &salen);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
                if (salen > 128)
@@ -1254,9 +1254,9 @@ extern void ves_icall_System_Net_Sockets_Socket_Connect_internal(SOCKET sock, Mo
        
        LOGDEBUG (g_message("%s: connecting to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), ntohs (((struct sockaddr_in *)sa)->sin_port)));
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_connect (sock, sa, sa_size);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
@@ -1288,7 +1288,7 @@ extern void ves_icall_System_Net_Sockets_Socket_Disconnect_internal(SOCKET sock,
        LPFN_DISCONNECTEX _wapi_disconnectex = NULL;
        LPFN_TRANSMITFILE _wapi_transmitfile = NULL;
        gboolean bret;
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        
        *error = 0;
        
@@ -1340,7 +1340,7 @@ extern void ves_icall_System_Net_Sockets_Socket_Disconnect_internal(SOCKET sock,
                *error = WSAGetLastError ();
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 }
 
 gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error)
@@ -1366,7 +1366,7 @@ gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArr
                return (0);
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 #ifdef HOST_WIN32
        {
                curthread->interrupt_on_stop = (gpointer)TRUE;
@@ -1376,7 +1376,7 @@ gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArr
 #else
        ret = _wapi_recv (sock, buf, count, recvflags);
 #endif
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
@@ -1442,9 +1442,9 @@ gint32 ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal(SOCKET sock, Mon
                return (0);
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_recvfrom (sock, buf, count, recvflags, sa, &sa_size);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==SOCKET_ERROR) {
                g_free(sa);
@@ -1492,9 +1492,9 @@ gint32 ves_icall_System_Net_Sockets_Socket_Send_internal(SOCKET sock, MonoArray
                return (0);
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_send (sock, buf, count, sendflags);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
                return(0);
@@ -1563,9 +1563,9 @@ gint32 ves_icall_System_Net_Sockets_Socket_SendTo_internal(SOCKET sock, MonoArra
                return (0);
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_sendto (sock, buf, count, sendflags, sa, sa_size);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
        }
@@ -2189,19 +2189,18 @@ void ves_icall_System_Net_Sockets_Socket_Shutdown_internal(SOCKET sock,
                                                           gint32 *error)
 {
        int ret;
-       MONO_PREPARE_BLOCKING
 
        *error = 0;
        
        /* Currently, the values for how (recv=0, send=1, both=2) match
         * the BSD API
         */
+       MONO_PREPARE_BLOCKING;
        ret = _wapi_shutdown (sock, how);
+       MONO_FINISH_BLOCKING;
        if(ret==SOCKET_ERROR) {
                *error = WSAGetLastError ();
        }
-
-       MONO_FINISH_BLOCKING
 }
 
 gint
@@ -2381,12 +2380,11 @@ MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, Mo
        char *hostname = mono_string_to_utf8 (host);
        int hint = get_addrinfo_family_hint ();
 
-       MONO_PREPARE_BLOCKING
-
        if (*hostname == '\0') {
                add_local_ips = TRUE;
                *h_name = host;
        }
+       MONO_PREPARE_BLOCKING;
        if (!add_local_ips && gethostname (this_hostname, sizeof (this_hostname)) != -1) {
                if (!strcmp (hostname, this_hostname)) {
                        add_local_ips = TRUE;
@@ -2398,7 +2396,7 @@ MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, Mo
                add_info_ok = FALSE;
 
        g_free(hostname);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (add_info_ok)
                return addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips);
@@ -2417,8 +2415,6 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *a
        int hint = get_addrinfo_family_hint ();
        gboolean add_info_ok;
 
-       MONO_PREPARE_BLOCKING
-
        address = mono_string_to_utf8 (addr);
 
        if (inet_pton (AF_INET, address, &saddr.sin_addr ) <= 0) {
@@ -2438,6 +2434,8 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *a
        }
        g_free(address);
 
+       MONO_PREPARE_BLOCKING;
+
        if(family == AF_INET) {
 #if HAVE_SOCKADDR_IN_SIN_LEN
                saddr.sin_len = sizeof (saddr);
@@ -2459,7 +2457,7 @@ extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *a
        }
 
        add_info_ok = !mono_get_address_info (hostname, 0, hint | MONO_HINT_CANONICAL_NAME | MONO_HINT_CONFIGURED_ONLY, &info);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (add_info_ok)
                return addrinfo_to_IPHostEntry (info, h_name, h_aliases, h_addr_list, FALSE);
index de24fcb0fa51d5c40bc1b613658527350e7653ed..47cbcfd599f3281305c628b8e82f994c2dd3bb02 100644 (file)
  *
  * Author:
  *     Mono Project (http://www.mono-project.com)
+ *     Ludovic Henry (ludovic@xamarin.com)
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2015 Xamarin, Inc (https://www.xamarin.com)
  */
+
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// Files:
+//  - src/classlibnative/float/floatnative.cpp
+//  - src/pal/src/cruntime/floatnative.cpp
+//
+// Ported from C++ to C and adjusted to Mono runtime
+
 #define __USE_ISOC99
+
 #include <math.h>
 #include <mono/metadata/sysmath.h>
-#include <mono/metadata/exception.h>
-
-#ifndef NAN
-# if G_BYTE_ORDER == G_BIG_ENDIAN
-#  define __nan_bytes           { 0x7f, 0xc0, 0, 0 }
-# endif
-# if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#  define __nan_bytes           { 0, 0, 0xc0, 0x7f }
-# endif
-
-static union { unsigned char __c[4]; float __d; } __nan_union = { __nan_bytes };
-# define NAN    (__nan_union.__d)
-#endif
-
-#ifndef HUGE_VAL
-#define __huge_val_t   union { unsigned char __c[8]; double __d; }
-# if G_BYTE_ORDER == G_BIG_ENDIAN
-#  define __HUGE_VAL_bytes       { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
-# endif
-# if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#  define __HUGE_VAL_bytes       { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
-# endif
-static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
-#  define HUGE_VAL      (__huge_val.__d)
-#endif
-
-
-gdouble ves_icall_System_Math_Floor (gdouble x) {
+
+#include "number-ms.h"
+#include "utils/mono-compiler.h"
+
+static const MonoDouble_double NaN = { .s = { .sign = 0x0, .exp = 0x7FF, .mantHi = 0x80000, .mantLo = 0x0 } };
+
+/* +Infinity */
+static const MonoDouble_double PInfinity = { .s = { .sign = 0x0, .exp = 0x7FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+/* -Infinity */
+static const MonoDouble_double MInfinity = { .s = { .sign = 0x1, .exp = 0x7FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+/* +1 */
+static const MonoDouble_double POne = { .s = { .sign = 0x0, .exp = 0x3FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+/* -1 */
+static const MonoDouble_double MOne = { .s = { .sign = 0x1, .exp = 0x3FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+static MONO_ALWAYS_INLINE gboolean
+isplusinfinity (gdouble d)
+{
+       return d == PInfinity.d;
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isminusinfinity (gdouble d)
+{
+       return d == MInfinity.d;
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isinfinity (gdouble d)
+{
+       return isplusinfinity (d) || isminusinfinity (d);
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isplusone (gdouble d)
+{
+       return d == POne.d;
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isminusone (gdouble d)
+{
+       return d == MOne.d;
+}
+
+gdouble
+ves_icall_System_Math_Floor (gdouble x)
+{
        return floor(x);
 }
 
-gdouble ves_icall_System_Math_Round (gdouble x) {
-       double int_part, dec_part;
+gdouble
+ves_icall_System_Math_Round (gdouble x)
+{
+       gdouble tmp, floor_tmp;
 
-       int_part = floor(x);
-       dec_part = x - int_part;
-       if (((dec_part == 0.5) &&
-               ((2.0 * ((int_part / 2.0) - floor(int_part / 2.0))) != 0.0)) ||
-               (dec_part > 0.5)) {
-               int_part++;
+       /* If the number has no fractional part do nothing This shortcut is necessary
+        * to workaround precision loss in borderline cases on some platforms */
+       if (x == (gdouble)(gint64) x)
+               return x;
+
+       tmp = x + 0.5;
+       floor_tmp = floor (tmp);
+
+       if (floor_tmp == tmp) {
+               if (fmod (tmp, 2.0) != 0)
+                       floor_tmp -= 1.0;
        }
-       return int_part;
-}
-
-gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits, gboolean away_from_zero) {
-#if !defined (HAVE_ROUND) || !defined (HAVE_RINT)
-       double int_part, dec_part;
-#endif
-       double p;
-
-       if (value == HUGE_VAL)
-               return HUGE_VAL;
-       if (value == -HUGE_VAL)
-               return -HUGE_VAL;
-       p = pow(10, digits);
-#if defined (HAVE_ROUND) && defined (HAVE_RINT)
-       if (away_from_zero)
-               return round (value * p) / p;
-       else
-               return rint (value * p) / p;
-#else
-       dec_part = modf (value, &int_part);
-       dec_part *= 1000000000000000ULL;
-       if (away_from_zero && dec_part > 0)
-               dec_part = ceil (dec_part);
-       else
-               dec_part = floor (dec_part);
-       dec_part /= (1000000000000000ULL / p);
-       if (away_from_zero) {
-               if (dec_part > 0)
-                       dec_part = floor (dec_part + 0.5);
-               else
-                       dec_part = ceil (dec_part - 0.5);
-       } else
-               dec_part = ves_icall_System_Math_Round (dec_part);
-       dec_part /= p;
-       return ves_icall_System_Math_Round ((int_part + dec_part) * p) / p;
-#endif
+
+       return copysign (floor_tmp, x);
 }
 
 gdouble 
@@ -130,7 +139,7 @@ gdouble
 ves_icall_System_Math_Acos (gdouble x)
 {
        if (x < -1 || x > 1)
-               return NAN;
+               return NaN.d;
 
        return acos (x);
 }
@@ -139,7 +148,7 @@ gdouble
 ves_icall_System_Math_Asin (gdouble x)
 {
        if (x < -1 || x > 1)
-               return NAN;
+               return NaN.d;
 
        return asin (x);
 }
@@ -153,21 +162,21 @@ ves_icall_System_Math_Atan (gdouble x)
 gdouble 
 ves_icall_System_Math_Atan2 (gdouble y, gdouble x)
 {
-       double result;
+       gdouble result;
+
+       if (isinfinity (x) && isinfinity (y))
+               return NaN.d;
 
-       if ((y == HUGE_VAL && x == HUGE_VAL) ||
-               (y == HUGE_VAL && x == -HUGE_VAL) ||
-               (y == -HUGE_VAL && x == HUGE_VAL) ||
-               (y == -HUGE_VAL && x == -HUGE_VAL)) {
-               return NAN;
-       }
        result = atan2 (y, x);
-       return (result == -0)? 0: result;
+       return result == -0.0 ? 0.0: result;
 }
 
 gdouble 
 ves_icall_System_Math_Exp (gdouble x)
 {
+       if (isinfinity (x))
+               return x < 0 ? 0.0 : x;
+
        return exp (x);
 }
 
@@ -175,9 +184,9 @@ gdouble
 ves_icall_System_Math_Log (gdouble x)
 {
        if (x == 0)
-               return -HUGE_VAL;
+               return MInfinity.d;
        else if (x < 0)
-               return NAN;
+               return NaN.d;
 
        return log (x);
 }
@@ -186,9 +195,9 @@ gdouble
 ves_icall_System_Math_Log10 (gdouble x)
 {
        if (x == 0)
-               return -HUGE_VAL;
+               return MInfinity.d;
        else if (x < 0)
-               return NAN;
+               return NaN.d;
 
        return log10 (x);
 }
@@ -196,43 +205,96 @@ ves_icall_System_Math_Log10 (gdouble x)
 gdouble 
 ves_icall_System_Math_Pow (gdouble x, gdouble y)
 {
-       double result;
-
-       if (isnan(x) || isnan(y)) {
-               return NAN;
-       }
-
-       if ((x == 1 || x == -1) && (y == HUGE_VAL || y == -HUGE_VAL)) {
-               return NAN;
+       gdouble result;
+
+       if (isnan (y))
+               return y;
+       if (isnan (x))
+               return x;
+
+       if (isinfinity (y)) {
+               if (isplusone (x))
+                       return x;
+               if (isminusone (x))
+                       return NaN.d;
        }
 
-       /* This code is for return the same results as MS.NET for certain
-        * limit values */
-       if (x < -9007199254740991.0) {
-               if (y > 9007199254740991.0)
-                       return HUGE_VAL;
-               if (y < -9007199254740991.0)
-                       return 0;
-       }
-
-       result = pow (x, y);
+       /* following are cases from PAL_pow which abstract the implementation of pow for posix and win32 platforms
+        * (https://github.com/dotnet/coreclr/blob/master/src/pal/src/cruntime/finite.cpp#L331) */
 
-       /* This code is for return the same results as MS.NET for certain
-        * limit values */
-       if (isnan(result) &&
-               (x == -1.0) &&
-               ((y > 9007199254740991.0) || (y < -9007199254740991.0))) {
-               return 1;
+       if (isplusinfinity (y) && !isnan (x)) {
+               if (isplusone (x) || isminusone (x))
+                       result = NaN.d;
+               else if (x > MOne.d && x < POne.d)
+                       result = 0.0;
+               else
+                       result = PInfinity.d;
+       } else if (isminusinfinity (y) && !isnan (x)) {
+               if (isplusone (x) || isminusone (x))
+                       result = NaN.d;
+               if (x > MOne.d && x < POne.d)
+                       result = PInfinity.d;
+               else
+                       result = 0.0;
+       } else if (x == 0.0 && y < 0.0) {
+               result = PInfinity.d;
+       } else if (y == 0.0 && isnan (x)) {
+               /* Windows returns NaN for pow(NaN, 0), but POSIX specifies
+                * a return value of 1 for that case.  We need to return
+                * the same result as Windows. */
+               result = NaN.d;
+       } else {
+               result = pow (x, y);
        }
 
-       return (result == -0)? 0: result;
+       if (result == PInfinity.d && x < 0.0 && isfinite (x) && ceil (y / 2) != floor (y / 2))
+               result = MInfinity.d;
+
+       /*
+        * The even/odd test in the if (this one and the one above) used to be ((long long) y % 2 == 0)
+        * on SPARC (long long) y for large y (>2**63) is always 0x7fffffff7fffffff, which
+        * is an odd number, so the test ((long long) y % 2 == 0) will always fail for
+        * large y. Since large double numbers are always even (e.g., the representation of
+        * 1E20+1 is the same as that of 1E20, the last .+1. is too insignificant to be part
+        * of the representation), this test will always return the wrong result for large y.
+        *
+        * The (ceil(y/2) == floor(y/2)) test is slower, but more robust.
+        */
+       if (result == MInfinity.d && x < 0.0 && isfinite (x) && ceil (y / 2) == floor (y / 2))
+               result = PInfinity.d;
+
+       return result == -0.0 ? 0 : result;
 }
 
 gdouble 
 ves_icall_System_Math_Sqrt (gdouble x)
 {
        if (x < 0)
-               return NAN;
+               return NaN.d;
 
        return sqrt (x);
 }
+
+gdouble
+ves_icall_System_Math_Abs_double (gdouble v)
+{
+       return fabs (v);
+}
+
+gfloat
+ves_icall_System_Math_Abs_single (gfloat v)
+{
+       return fabsf (v);
+}
+
+gdouble
+ves_icall_System_Math_Ceiling (gdouble v)
+{
+       return ceil (v);
+}
+
+gdouble
+ves_icall_System_Math_SplitFractionDouble (gdouble *v)
+{
+       return modf (*v, v);
+}
index f8f5778ab418c7fdd52f28a9f8f6cc311d3b9815..bb3cf92bfd5d1906d1a53e04f4c59a0cdacc5e87 100644 (file)
@@ -3,8 +3,10 @@
  *
  * Author:
  *   Dan Lewis (dihlewis@yahoo.co.uk)
+ *   Ludovic Henry (ludovic@xamarin.com)
  *
  * (C) Ximian, Inc. 2002
+ * Copyright 2015 Xamarin, Inc (https://www.xamarin.com)
  */
 
 #ifndef __METADATA_SYSMATH_H__
 
 #include <config.h>
 #include <glib.h>
-#include "mono/utils/mono-compiler.h"
 
-extern gdouble ves_icall_System_Math_Floor (gdouble x);
-extern gdouble ves_icall_System_Math_Round (gdouble x);
-extern gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits, gboolean away_from_zero);
+gdouble
+ves_icall_System_Math_Floor (gdouble x);
 
-extern gdouble 
+gdouble
+ves_icall_System_Math_Round (gdouble x);
+
+gdouble
 ves_icall_System_Math_Sin (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Cos (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Tan (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Sinh (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Cosh (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Tanh (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Acos (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Asin (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Atan (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Atan2 (gdouble y, gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Exp (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Log (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Log10 (gdouble x);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Pow (gdouble x, gdouble y);
 
-extern gdouble 
+gdouble
 ves_icall_System_Math_Sqrt (gdouble x);
 
+gdouble
+ves_icall_System_Math_Abs_double (gdouble v);
+
+gfloat
+ves_icall_System_Math_Abs_single (gfloat v);
+
+gdouble
+ves_icall_System_Math_SplitFractionDouble (gdouble *v);
+
+gdouble
+ves_icall_System_Math_Ceiling (gdouble v);
+
 #endif
index b7deef04375ac1cb7c669f40a1ba7ab970a1ce7b..bf619214c8557f19a08553296a81a69719ee3d1c 100644 (file)
@@ -57,37 +57,44 @@ epoll_cleanup (void)
 static void
 epoll_register_fd (gint fd, gint events, gboolean is_new)
 {
-       if (events == 0) {
-               if (!is_new && epoll_ctl (epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1)
-                       g_error ("epoll_register_fd: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno));
-       } else {
-               struct epoll_event event;
+       struct epoll_event event;
 
 #ifndef EPOLLONESHOT
 /* it was only defined on android in May 2013 */
 #define EPOLLONESHOT 0x40000000
 #endif
 
-               event.data.fd = fd;
-               event.events = EPOLLONESHOT;
-               if ((events & MONO_POLLIN) != 0)
-                       event.events |= EPOLLIN;
-               if ((events & MONO_POLLOUT) != 0)
-                       event.events |= EPOLLOUT;
+       event.data.fd = fd;
+       event.events = EPOLLONESHOT;
+       if ((events & EVENT_IN) != 0)
+               event.events |= EPOLLIN;
+       if ((events & EVENT_OUT) != 0)
+               event.events |= EPOLLOUT;
 
-               if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1)
-                       g_error ("epoll_register_fd: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno));
-       }
+       if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1)
+               g_error ("epoll_register_fd: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno));
+}
+
+static void
+epoll_remove_fd (gint fd)
+{
+       if (epoll_ctl (epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1)
+                       g_error ("epoll_remove_fd: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno));
 }
 
 static gint
-epoll_event_wait (void)
+epoll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
 {
-       gint ready;
+       gint i, ready;
 
        memset (epoll_events, 0, sizeof (struct epoll_event) * EPOLL_NEVENTS);
 
+       mono_gc_set_skip_thread (TRUE);
+
        ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1);
+
+       mono_gc_set_skip_thread (FALSE);
+
        if (ready == -1) {
                switch (errno) {
                case EINTR:
@@ -100,33 +107,30 @@ epoll_event_wait (void)
                }
        }
 
-       return ready;
-}
+       if (ready == -1)
+               return -1;
 
-static gint
-epoll_event_get_fd_max (void)
-{
-       return EPOLL_NEVENTS;
-}
+       for (i = 0; i < ready; ++i) {
+               gint fd, events = 0;
 
-static gint
-epoll_event_get_fd_at (gint i, gint *events)
-{
-       g_assert (events);
+               fd = epoll_events [i].data.fd;
+               if (epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
+                       events |= EVENT_IN;
+               if (epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
+                       events |= EVENT_OUT;
 
-       *events = ((epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) ? MONO_POLLIN : 0)
-                   | ((epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) ? MONO_POLLOUT : 0);
+               callback (fd, events, user_data);
+       }
 
-       return epoll_events [i].data.fd;
+       return 0;
 }
 
 static ThreadPoolIOBackend backend_epoll = {
        .init = epoll_init,
        .cleanup = epoll_cleanup,
        .register_fd = epoll_register_fd,
+       .remove_fd = epoll_remove_fd,
        .event_wait = epoll_event_wait,
-       .event_get_fd_max = epoll_event_get_fd_max,
-       .event_get_fd_at = epoll_event_get_fd_at,
 };
 
 #endif
index b06ea74aa1e11ee189cb0a12f3f499cfb5a8cd5c..093d3399dc947736f20140470c3ef08cfa306aa0 100644 (file)
 static gint kqueue_fd;
 static struct kevent *kqueue_events;
 
-static gboolean
-kqueue_init (gint wakeup_pipe_fd)
+static gint
+KQUEUE_INIT_FD (gint fd, gint events, gint flags)
 {
        struct kevent event;
+       EV_SET (&event, fd, events, flags, 0, 0, 0);
+       return kevent (kqueue_fd, &event, 1, NULL, 0, NULL);
+}
 
+static gboolean
+kqueue_init (gint wakeup_pipe_fd)
+{
        kqueue_fd = kqueue ();
        if (kqueue_fd == -1) {
-               g_warning ("kqueue_init: kqueue () failed, error (%d) %s", errno, g_strerror (errno));
+               g_error ("kqueue_init: kqueue () failed, error (%d) %s", errno, g_strerror (errno));
                return FALSE;
        }
 
-       EV_SET (&event, wakeup_pipe_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
-       if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1) {
-               g_warning ("kqueue_init: kevent () failed, error (%d) %s", errno, g_strerror (errno));
+       if (KQUEUE_INIT_FD (wakeup_pipe_fd, EVFILT_READ, EV_ADD | EV_ENABLE) == -1) {
+               g_error ("kqueue_init: kevent () failed, error (%d) %s", errno, g_strerror (errno));
                close (kqueue_fd);
                return FALSE;
        }
@@ -48,26 +53,45 @@ kqueue_cleanup (void)
 static void
 kqueue_register_fd (gint fd, gint events, gboolean is_new)
 {
-       struct kevent event;
-
-       if (events == 0)
-               return;
-
-       if ((events & MONO_POLLIN) != 0)
-               EV_SET (&event, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
-       if ((events & MONO_POLLOUT) != 0)
-               EV_SET (&event, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
+       if (events & EVENT_IN) {
+               if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_ADD | EV_ENABLE) == -1)
+                       g_error ("kqueue_register_fd: kevent(read,enable) failed, error (%d) %s", errno, g_strerror (errno));
+       } else {
+               if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_ADD | EV_DISABLE) == -1)
+                       g_error ("kqueue_register_fd: kevent(read,disable) failed, error (%d) %s", errno, g_strerror (errno));
+       }
+       if (events & EVENT_OUT) {
+               if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_ADD | EV_ENABLE) == -1)
+                       g_error ("kqueue_register_fd: kevent(write,enable) failed, error (%d) %s", errno, g_strerror (errno));
+       } else {
+               if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_ADD | EV_DISABLE) == -1)
+                       g_error ("kqueue_register_fd: kevent(write,disable) failed, error (%d) %s", errno, g_strerror (errno));
+       }
+}
 
-       if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1)
-               g_warning ("kqueue_register_fd: kevent(update) failed, error (%d) %s", errno, g_strerror (errno));
+static void
+kqueue_remove_fd (gint fd)
+{
+       /* FIXME: a race between closing and adding operation in the Socket managed code trigger a ENOENT error */
+       if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_DELETE) == -1)
+               g_error ("kqueue_register_fd: kevent(read,delete) failed, error (%d) %s", errno, g_strerror (errno));
+       if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_DELETE) == -1)
+               g_error ("kqueue_register_fd: kevent(write,delete) failed, error (%d) %s", errno, g_strerror (errno));
 }
 
 static gint
-kqueue_event_wait (void)
+kqueue_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
 {
-       gint ready;
+       gint i, ready;
+
+       memset (kqueue_events, 0, sizeof (struct kevent) * KQUEUE_NEVENTS);
+
+       mono_gc_set_skip_thread (TRUE);
 
        ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
+
+       mono_gc_set_skip_thread (FALSE);
+
        if (ready == -1) {
                switch (errno) {
                case EINTR:
@@ -75,38 +99,35 @@ kqueue_event_wait (void)
                        ready = 0;
                        break;
                default:
-                       g_warning ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
+                       g_error ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
                        break;
                }
        }
 
-       return ready;
-}
+       if (ready == -1)
+               return -1;
 
-static gint
-kqueue_event_get_fd_at (gint i, gint *events)
-{
-       g_assert (events);
+       for (i = 0; i < ready; ++i) {
+               gint fd, events = 0;
 
-       *events = ((kqueue_events [i].filter == EVFILT_READ || (kqueue_events [i].flags & EV_ERROR) != 0) ? MONO_POLLIN : 0)
-                   | ((kqueue_events [i].filter == EVFILT_WRITE || (kqueue_events [i].flags & EV_ERROR) != 0) ? MONO_POLLOUT : 0);
+               fd = kqueue_events [i].ident;
+               if (kqueue_events [i].filter == EVFILT_READ || (kqueue_events [i].flags & EV_ERROR) != 0)
+                       events |= EVENT_IN;
+               if (kqueue_events [i].filter == EVFILT_WRITE || (kqueue_events [i].flags & EV_ERROR) != 0)
+                       events |= EVENT_OUT;
 
-       return kqueue_events [i].ident;
-}
+               callback (fd, events, user_data);
+       }
 
-static gint
-kqueue_event_get_fd_max (void)
-{
-       return KQUEUE_NEVENTS;
+       return 0;
 }
 
 static ThreadPoolIOBackend backend_kqueue = {
        .init = kqueue_init,
        .cleanup = kqueue_cleanup,
        .register_fd = kqueue_register_fd,
+       .remove_fd = kqueue_remove_fd,
        .event_wait = kqueue_event_wait,
-       .event_get_fd_max = kqueue_event_get_fd_max,
-       .event_get_fd_at = kqueue_event_get_fd_at,
 };
 
 #endif
index 88bdc9f839be81a2bdcff84a7f8ae9207143ca55..a02ceea4c50411148fc47ec79dd5d38b7a449c9c 100644 (file)
@@ -1,5 +1,24 @@
 
-#define POLL_NEVENTS 1024
+#if defined(HAVE_POLL)
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+typedef struct pollfd mono_pollfd;
+
+#elif defined(HOST_WIN32)
+
+#include "mswsock.h"
+
+typedef WSAPOLLFD mono_pollfd;
+
+#else
+/* poll is not defined */
+#error
+#endif
 
 static mono_pollfd *poll_fds;
 static guint poll_fds_capacity;
@@ -16,15 +35,20 @@ POLL_INIT_FD (mono_pollfd *poll_fd, gint fd, gint events)
 static gboolean
 poll_init (gint wakeup_pipe_fd)
 {
-       guint i;
+       gint i;
+
+       poll_fds_size = wakeup_pipe_fd + 1;
+       poll_fds_capacity = 64;
+
+       while (wakeup_pipe_fd >= poll_fds_capacity)
+               poll_fds_capacity *= 4;
 
-       poll_fds_size = 1;
-       poll_fds_capacity = POLL_NEVENTS;
        poll_fds = g_new0 (mono_pollfd, poll_fds_capacity);
 
-       POLL_INIT_FD (poll_fds, wakeup_pipe_fd, MONO_POLLIN);
-       for (i = 1; i < poll_fds_capacity; ++i)
-               POLL_INIT_FD (poll_fds + i, -1, 0);
+       for (i = 0; i < wakeup_pipe_fd; ++i)
+               POLL_INIT_FD (&poll_fds [i], -1, 0);
+
+       POLL_INIT_FD (&poll_fds [wakeup_pipe_fd], wakeup_pipe_fd, POLLIN);
 
        return TRUE;
 }
@@ -35,91 +59,80 @@ poll_cleanup (void)
        g_free (poll_fds);
 }
 
-static inline gint
-poll_mark_bad_fds (mono_pollfd *poll_fds, gint poll_fds_size)
+static void
+poll_register_fd (gint fd, gint events, gboolean is_new)
 {
        gint i;
-       gint ret;
-       gint ready = 0;
        mono_pollfd *poll_fd;
 
-       for (i = 0; i < poll_fds_size; i++) {
-               poll_fd = poll_fds + i;
-               if (poll_fd->fd == -1)
-                       continue;
+       g_assert (fd >= 0);
+       g_assert (poll_fds_size <= poll_fds_capacity);
 
-               ret = mono_poll (poll_fd, 1, 0);
-               if (ret == 1)
-                       ready++;
-               if (ret == -1) {
-#if !defined(HOST_WIN32)
-                       if (errno == EBADF)
-#else
-                       if (WSAGetLastError () == WSAEBADF)
-#endif
-                       {
-                               poll_fd->revents |= MONO_POLLNVAL;
-                               ready++;
-                       }
-               }
-       }
+       if (fd >= poll_fds_capacity) {
+               do {
+                       poll_fds_capacity *= 4;
+               } while (fd >= poll_fds_capacity);
 
-       return ready;
-}
+               poll_fds = g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
+       }
 
-static void
-poll_register_fd (gint fd, gint events, gboolean is_new)
-{
-       gboolean found = FALSE;
-       gint j, k;
+       if (fd >= poll_fds_size) {
+               for (i = poll_fds_size; i <= fd; ++i)
+                       POLL_INIT_FD (&poll_fds [i], -1, 0);
 
-       for (j = 1; j < poll_fds_size; ++j) {
-               mono_pollfd *poll_fd = poll_fds + j;
-               if (poll_fd->fd == fd) {
-                       found = TRUE;
-                       break;
-               }
+               poll_fds_size = fd + 1;
        }
 
-       if (events == 0) {
-               if (found)
-                       POLL_INIT_FD (poll_fds + j, -1, 0);
-               return;
-       }
+       poll_fd = &poll_fds [fd];
 
-       if (!found) {
-               for (j = 1; j < poll_fds_capacity; ++j) {
-                       mono_pollfd *poll_fd = poll_fds + j;
-                       if (poll_fd->fd == -1)
-                               break;
-               }
+       if (poll_fd->fd != -1) {
+               g_assert (poll_fd->fd == fd);
+               g_assert (!is_new);
        }
 
-       if (j == poll_fds_capacity) {
-               poll_fds_capacity += POLL_NEVENTS;
-               poll_fds = g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
-               for (k = j; k < poll_fds_capacity; ++k)
-                       POLL_INIT_FD (poll_fds + k, -1, 0);
-       }
+       POLL_INIT_FD (poll_fd, fd, ((events & EVENT_IN) ? POLLIN : 0) | ((events & EVENT_OUT) ? POLLOUT : 0));
+}
+
+static void
+poll_remove_fd (gint fd)
+{
+       mono_pollfd *poll_fd;
 
-       POLL_INIT_FD (poll_fds + j, fd, events);
+       g_assert (fd >= 0);
 
-       if (j >= poll_fds_size)
-               poll_fds_size = j + 1;
+       g_assert (fd < poll_fds_size);
+       poll_fd = &poll_fds [fd];
+
+       g_assert (poll_fd->fd == fd);
+       POLL_INIT_FD (poll_fd, -1, 0);
 }
 
 static gint
-poll_event_wait (void)
+poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
 {
-       gint ready;
+       gint i, ready;
+
+       for (i = 0; i < poll_fds_size; ++i)
+               poll_fds [i].revents = 0;
+
+       mono_gc_set_skip_thread (TRUE);
+
+#if !defined(HOST_WIN32)
+       ready = poll (poll_fds, poll_fds_size, -1);
+#else
+       ready = WSAPoll(poll_fds, poll_fds_size, -1);
+       if (ready == SOCKET_ERROR)
+               ready = -1;
+#endif
+
+       mono_gc_set_skip_thread (FALSE);
 
-       ready = mono_poll (poll_fds, poll_fds_size, -1);
        if (ready == -1) {
                /*
                 * Apart from EINTR, we only check EBADF, for the rest:
                 *  EINVAL: mono_poll() 'protects' us from descriptor
                 *      numbers above the limit if using select() by marking
-                *      then as MONO_POLLERR.  If a system poll() is being
+                *      then as POLLERR.  If a system poll() is being
                 *      used, the number of descriptor we're passing will not
                 *      be over sysconf(_SC_OPEN_MAX), as the error would have
                 *      happened when opening.
@@ -139,53 +152,51 @@ poll_event_wait (void)
 #else
                case WSAEINTR:
 #endif
+               {
                        mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
                        ready = 0;
                        break;
-#if !defined(HOST_WIN32)
-               case EBADF:
-#else
-               case WSAEBADF:
-#endif
-                       ready = poll_mark_bad_fds (poll_fds, poll_fds_size);
-                       break;
+               }
                default:
 #if !defined(HOST_WIN32)
-                       g_warning ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
+                       g_error ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
 #else
-                       g_warning ("poll_event_wait: mono_poll () failed, error (%d)\n", WSAGetLastError ());
+                       g_error ("poll_event_wait: mono_poll () failed, error (%d)\n", WSAGetLastError ());
 #endif
                        break;
                }
        }
 
-       return ready;
-}
+       if (ready == -1)
+               return -1;
 
-static gint
-poll_event_get_fd_at (gint i, gint *events)
-{
-       g_assert (events);
+       for (i = 0; i < poll_fds_size; ++i) {
+               gint fd, events = 0;
+
+               if (poll_fds [i].fd == -1)
+                       continue;
+               if (poll_fds [i].revents == 0)
+                       continue;
 
-       *events = ((poll_fds [i].revents & (MONO_POLLIN | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)) ? MONO_POLLIN : 0)
-                   | ((poll_fds [i].revents & (MONO_POLLOUT | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)) ? MONO_POLLOUT : 0);
+               fd = poll_fds [i].fd;
+               if (poll_fds [i].revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL))
+                       events |= EVENT_IN;
+               if (poll_fds [i].revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
+                       events |= EVENT_OUT;
 
-       /* if nothing happened on the fd, then just return
-        * an invalid fd number so it is discarded */
-       return poll_fds [i].revents == 0 ? -1 : poll_fds [i].fd;
-}
+               callback (fd, events, user_data);
 
-static gint
-poll_event_get_fd_max (void)
-{
-       return poll_fds_size;
+               if (--ready == 0)
+                       break;
+       }
+
+       return 0;
 }
 
 static ThreadPoolIOBackend backend_poll = {
        .init = poll_init,
        .cleanup = poll_cleanup,
        .register_fd = poll_register_fd,
+       .remove_fd = poll_remove_fd,
        .event_wait = poll_event_wait,
-       .event_get_fd_max = poll_event_get_fd_max,
-       .event_get_fd_at = poll_event_get_fd_at,
 };
index 3853f8496288a2826c3cb69eb59b67d3a6b1181a..d6f8b25b2521e381534cefb1f05561bdf72accea 100644 (file)
 #include <mono/metadata/threadpool-ms.h>
 #include <mono/metadata/threadpool-ms-io.h>
 #include <mono/utils/atomic.h>
-#include <mono/utils/mono-poll.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-lazy-init.h>
+#include <mono/utils/mono-logger-internal.h>
 
 typedef struct {
        gboolean (*init) (gint wakeup_pipe_fd);
        void     (*cleanup) (void);
        void     (*register_fd) (gint fd, gint events, gboolean is_new);
-       gint     (*event_wait) (void);
-       gint     (*event_get_fd_max) (void);
-       gint     (*event_get_fd_at) (gint i, gint *events);
+       void     (*remove_fd) (gint fd);
+       gint     (*event_wait) (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data);
 } ThreadPoolIOBackend;
 
+enum {
+       EVENT_IN   = 1 << 0,
+       EVENT_OUT  = 1 << 1,
+} ThreadPoolIOEvent;
+
 #include "threadpool-ms-io-epoll.c"
 #include "threadpool-ms-io-kqueue.c"
 #include "threadpool-ms-io-poll.c"
 
+#define UPDATES_CAPACITY 128
+
 /* Keep in sync with System.Net.Sockets.Socket.SocketOperation */
 enum {
        AIO_OP_FIRST,
@@ -62,23 +68,42 @@ enum {
        AIO_OP_LAST
 };
 
+typedef enum {
+       UPDATE_EMPTY = 0,
+       UPDATE_ADD,
+       UPDATE_REMOVE_SOCKET,
+       UPDATE_REMOVE_DOMAIN,
+} ThreadPoolIOUpdateType;
+
 typedef struct {
        gint fd;
        MonoSocketAsyncResult *sockares;
-} ThreadPoolIOUpdate;
+} ThreadPoolIOUpdate_Add;
 
 typedef struct {
-       ThreadPoolIOBackend backend;
+       gint fd;
+} ThreadPoolIOUpdate_RemoveSocket;
 
-       mono_mutex_t lock;
+typedef struct {
+       MonoDomain *domain;
+} ThreadPoolIOUpdate_RemoveDomain;
 
-       mono_cond_t updates_signal;
+typedef struct {
+       ThreadPoolIOUpdateType type;
+       union {
+               ThreadPoolIOUpdate_Add add;
+               ThreadPoolIOUpdate_RemoveSocket remove_socket;
+               ThreadPoolIOUpdate_RemoveDomain remove_domain;
+       } data;
+} ThreadPoolIOUpdate;
 
-       MonoGHashTable *states;
+typedef struct {
+       ThreadPoolIOBackend backend;
 
-       ThreadPoolIOUpdate *updates;
-       guint updates_size;
-       guint updates_capacity;
+       ThreadPoolIOUpdate updates [UPDATES_CAPACITY];
+       gint updates_size;
+       mono_mutex_t updates_lock;
+       mono_cond_t updates_cond;
 
 #if !defined(HOST_WIN32)
        gint wakeup_pipes [2];
@@ -104,14 +129,14 @@ get_events_from_sockares (MonoSocketAsyncResult *ares)
        case AIO_OP_READPIPE:
        case AIO_OP_ACCEPTRECEIVE:
        case AIO_OP_RECEIVE_BUFFERS:
-               return MONO_POLLIN;
+               return EVENT_IN;
        case AIO_OP_SEND:
        case AIO_OP_SEND_JUST_CALLBACK:
        case AIO_OP_SENDTO:
        case AIO_OP_CONNECT:
        case AIO_OP_SEND_BUFFERS:
        case AIO_OP_DISCONNECT:
-               return MONO_POLLOUT;
+               return EVENT_OUT;
        default:
                g_assert_not_reached ();
        }
@@ -141,128 +166,12 @@ get_events (MonoMList *list)
        MonoMList *current;
        gint events = 0;
 
-       for (current = list; current; current = mono_mlist_next (current)) {
-               MonoSocketAsyncResult *ares = (MonoSocketAsyncResult*) mono_mlist_get_data (current);
-               if (ares)
-                       events |= get_events_from_sockares (ares);
-       }
+       for (current = list; current; current = mono_mlist_next (current))
+               events |= get_events_from_sockares ((MonoSocketAsyncResult*) mono_mlist_get_data (current));
 
        return events;
 }
 
-static void
-selector_thread_wakeup (void);
-
-/*
- * If sockares is NULL, then it means we want to delete the corresponding fd
- */
-static void
-update_add (gint fd, MonoSocketAsyncResult *sockares)
-{
-       ThreadPoolIOUpdate *update;
-
-       mono_mutex_lock (&threadpool_io->lock);
-
-       threadpool_io->updates_size += 1;
-       if (threadpool_io->updates_size > threadpool_io->updates_capacity) {
-               ThreadPoolIOUpdate *updates_new, *updates_old;
-               gint updates_new_capacity, updates_old_capacity;
-
-               updates_old_capacity = threadpool_io->updates_capacity;
-               updates_new_capacity = updates_old_capacity + 16;
-
-               updates_old = threadpool_io->updates;
-               updates_new = mono_gc_alloc_fixed (sizeof (ThreadPoolIOUpdate) * updates_new_capacity, MONO_GC_DESCRIPTOR_NULL);
-               g_assert (updates_new);
-
-               if (updates_old)
-                       memcpy (updates_new, updates_old, sizeof (ThreadPoolIOUpdate) * updates_old_capacity);
-
-               threadpool_io->updates = updates_new;
-               threadpool_io->updates_capacity = updates_new_capacity;
-
-               if (updates_old)
-                       mono_gc_free_fixed (updates_old);
-       }
-
-       update = &threadpool_io->updates [threadpool_io->updates_size - 1];
-       update->fd = fd;
-       update->sockares = sockares;
-
-       selector_thread_wakeup ();
-
-       mono_cond_wait (&threadpool_io->updates_signal, &threadpool_io->lock);
-
-       mono_mutex_unlock (&threadpool_io->lock);
-}
-
-static void
-update_drain (void (*callback) (gint fd, gint events, gboolean is_new))
-{
-       gint i;
-
-       mono_mutex_lock (&threadpool_io->lock);
-
-       for (i = 0; i < threadpool_io->updates_size; ++i) {
-               ThreadPoolIOUpdate *update;
-               MonoMList *list = NULL;
-               gpointer k;
-               gboolean is_new;
-
-               update = &threadpool_io->updates [i];
-
-               is_new = !mono_g_hash_table_lookup_extended (threadpool_io->states, GINT_TO_POINTER (update->fd), &k, (gpointer*) &list);
-
-               if (!update->sockares) {
-                       callback (update->fd, 0, is_new);
-               } else {
-                       list = mono_mlist_append (list, (MonoObject*) update->sockares);
-                       mono_g_hash_table_replace (threadpool_io->states, update->sockares->handle, list);
-
-                       callback (update->fd, get_events (list), is_new);
-               }
-       }
-
-       mono_cond_broadcast (&threadpool_io->updates_signal);
-
-       if (threadpool_io->updates_size > 0) {
-               ThreadPoolIOUpdate *updates_old;
-
-               threadpool_io->updates_size = 0;
-               threadpool_io->updates_capacity = 16;
-
-               updates_old = threadpool_io->updates;
-
-               threadpool_io->updates = mono_gc_alloc_fixed (sizeof (ThreadPoolIOUpdate) * threadpool_io->updates_capacity, MONO_GC_DESCRIPTOR_NULL);
-               g_assert (threadpool_io->updates);
-
-               mono_gc_free_fixed (updates_old);
-       }
-
-       mono_mutex_unlock (&threadpool_io->lock);
-}
-
-static void
-update_remove (gboolean (*predicate) (ThreadPoolIOUpdate *update, gpointer user_data), gpointer user_data)
-{
-       gint i;
-
-       mono_mutex_lock (&threadpool_io->lock);
-
-       for (i = 0; i < threadpool_io->updates_size; ++i) {
-               if (predicate (&threadpool_io->updates [i], user_data)) {
-                       if (i < threadpool_io->updates_size - 1)
-                               memmove (threadpool_io->updates + i, threadpool_io->updates + i + 1, sizeof (ThreadPoolIOUpdate) * threadpool_io->updates_size - i - 1);
-                       memset (threadpool_io->updates + threadpool_io->updates_size - 1, 0, sizeof (ThreadPoolIOUpdate));
-
-                       threadpool_io->updates_size --;
-                       i --;
-               }
-       }
-
-       mono_mutex_unlock (&threadpool_io->lock);
-}
-
 static void
 selector_thread_wakeup (void)
 {
@@ -319,9 +228,104 @@ selector_thread_wakeup_drain_pipes (void)
        }
 }
 
+typedef struct {
+       MonoDomain *domain;
+       MonoGHashTable *states;
+} FilterSockaresForDomainData;
+
+static void
+filter_sockares_for_domain (gpointer key, gpointer value, gpointer user_data)
+{
+       FilterSockaresForDomainData *data;
+       MonoMList *list = value, *element;
+       MonoDomain *domain;
+       MonoGHashTable *states;
+
+       g_assert (user_data);
+       data = user_data;
+       domain = data->domain;
+       states = data->states;
+
+       for (element = list; element; element = mono_mlist_next (element)) {
+               MonoSocketAsyncResult *sockares = (MonoSocketAsyncResult*) mono_mlist_get_data (element);
+               if (mono_object_domain (sockares) == domain)
+                       mono_mlist_set_data (element, NULL);
+       }
+
+       /* we skip all the first elements which are NULL */
+       for (; list; list = mono_mlist_next (list)) {
+               if (mono_mlist_get_data (list))
+                       break;
+       }
+
+       if (list) {
+               g_assert (mono_mlist_get_data (list));
+
+               /* we delete all the NULL elements after the first one */
+               for (element = list; element;) {
+                       MonoMList *next;
+                       if (!(next = mono_mlist_next (element)))
+                               break;
+                       if (mono_mlist_get_data (next))
+                               element = next;
+                       else
+                               mono_mlist_set_next (element, mono_mlist_next (next));
+               }
+       }
+
+       mono_g_hash_table_replace (states, key, list);
+}
+
+static void
+wait_callback (gint fd, gint events, gpointer user_data)
+{
+       if (mono_runtime_is_shutting_down ())
+               return;
+
+       if (fd == threadpool_io->wakeup_pipes [0]) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wke");
+               selector_thread_wakeup_drain_pipes ();
+       } else {
+               MonoGHashTable *states;
+               MonoMList *list = NULL;
+               gpointer k;
+
+               g_assert (user_data);
+               states = user_data;
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: cal fd %3d, events = %2s | %2s",
+                       fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..");
+
+               if (!mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list))
+                       g_error ("wait_callback: fd %d not found in states table", fd);
+
+               if (list && (events & EVENT_IN) != 0) {
+                       MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, EVENT_IN);
+                       if (sockares)
+                               mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
+               }
+               if (list && (events & EVENT_OUT) != 0) {
+                       MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, EVENT_OUT);
+                       if (sockares)
+                               mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
+               }
+
+               mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list);
+
+               events = get_events (list);
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: res fd %3d, events = %2s | %2s",
+                       fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..");
+
+               threadpool_io->backend.register_fd (fd, events, FALSE);
+       }
+}
+
 static void
 selector_thread (gpointer data)
 {
+       MonoGHashTable *states;
+
        io_selector_running = TRUE;
 
        if (mono_runtime_is_shutting_down ()) {
@@ -329,73 +333,138 @@ selector_thread (gpointer data)
                return;
        }
 
-       mono_mutex_lock (&threadpool_io->lock);
+       states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC);
 
        for (;;) {
-               guint i;
-               guint max;
-               gint ready = 0;
-
-               update_drain (threadpool_io->backend.register_fd);
+               gint i, j;
+               gint res;
 
-               mono_mutex_unlock (&threadpool_io->lock);
+               mono_mutex_lock (&threadpool_io->updates_lock);
 
-               mono_gc_set_skip_thread (TRUE);
+               for (i = 0; i < threadpool_io->updates_size; ++i) {
+                       ThreadPoolIOUpdate *update = &threadpool_io->updates [i];
 
-               ready = threadpool_io->backend.event_wait ();
+                       switch (update->type) {
+                       case UPDATE_EMPTY:
+                               break;
+                       case UPDATE_ADD: {
+                               gint fd;
+                               gint events;
+                               gpointer k;
+                               gboolean exists;
+                               MonoMList *list = NULL;
+                               MonoSocketAsyncResult *sockares;
 
-               mono_gc_set_skip_thread (FALSE);
+                               fd = update->data.add.fd;
+                               g_assert (fd >= 0);
 
-               mono_mutex_lock (&threadpool_io->lock);
+                               sockares = update->data.add.sockares;
+                               g_assert (sockares);
 
-               if (ready == -1 || mono_runtime_is_shutting_down ())
-                       break;
+                               exists = mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list);
+                               list = mono_mlist_append (list, (MonoObject*) sockares);
+                               mono_g_hash_table_replace (states, sockares->handle, list);
 
-               max = threadpool_io->backend.event_get_fd_max ();
+                               events = get_events (list);
 
-               for (i = 0; i < max && ready > 0; ++i) {
-                       gint events;
-                       gint fd = threadpool_io->backend.event_get_fd_at (i, &events);
+                               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: %3s fd %3d, events = %2s | %2s",
+                                       exists ? "mod" : "add", fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..");
 
-                       if (fd == -1)
-                               continue;
+                               threadpool_io->backend.register_fd (fd, events, !exists);
 
-                       if (fd == threadpool_io->wakeup_pipes [0]) {
-                               selector_thread_wakeup_drain_pipes ();
-                       } else {
-                               MonoMList *list = NULL;
+                               break;
+                       }
+                       case UPDATE_REMOVE_SOCKET: {
+                               gint fd;
                                gpointer k;
+                               MonoMList *list = NULL;
 
-                               if (mono_g_hash_table_lookup_extended (threadpool_io->states, GINT_TO_POINTER (fd), &k, (gpointer*) &list)) {
-                                       if (list && (events & MONO_POLLIN) != 0) {
-                                               MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, MONO_POLLIN);
-                                               if (sockares)
-                                                       mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
-                                       }
-                                       if (list && (events & MONO_POLLOUT) != 0) {
-                                               MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, MONO_POLLOUT);
-                                               if (sockares)
-                                                       mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
+                               fd = update->data.remove_socket.fd;
+                               g_assert (fd >= 0);
+
+                               if (mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list)) {
+                                       mono_g_hash_table_remove (states, GINT_TO_POINTER (fd));
+
+                                       for (j = i + 1; j < threadpool_io->updates_size; ++j) {
+                                               ThreadPoolIOUpdate *update = &threadpool_io->updates [j];
+                                               if (update->type == UPDATE_ADD && update->data.add.fd == fd)
+                                                       memset (update, 0, sizeof (ThreadPoolIOUpdate));
                                        }
 
-                                       if (!list)
-                                               mono_g_hash_table_remove (threadpool_io->states, GINT_TO_POINTER (fd));
-                                       else
-                                               mono_g_hash_table_replace (threadpool_io->states, GINT_TO_POINTER (fd), list);
+                                       for (; list; list = mono_mlist_remove_item (list, list))
+                                               mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list));
 
-                                       threadpool_io->backend.register_fd (fd, get_events (list), FALSE);
+                                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: del fd %3d", fd);
+                                       threadpool_io->backend.remove_fd (fd);
                                }
+
+                               break;
+                       }
+                       case UPDATE_REMOVE_DOMAIN: {
+                               MonoDomain *domain;
+
+                               domain = update->data.remove_domain.domain;
+                               g_assert (domain);
+
+                               FilterSockaresForDomainData user_data = { .domain = domain, .states = states };
+                               mono_g_hash_table_foreach (states, filter_sockares_for_domain, &user_data);
+
+                               for (j = i + 1; j < threadpool_io->updates_size; ++j) {
+                                       ThreadPoolIOUpdate *update = &threadpool_io->updates [j];
+                                       if (update->type == UPDATE_ADD && mono_object_domain (update->data.add.sockares) == domain)
+                                               memset (update, 0, sizeof (ThreadPoolIOUpdate));
+                               }
+
+                               break;
+                       }
+                       default:
+                               g_assert_not_reached ();
                        }
+               }
 
-                       ready -= 1;
+               mono_cond_broadcast (&threadpool_io->updates_cond);
+
+               if (threadpool_io->updates_size > 0) {
+                       threadpool_io->updates_size = 0;
+                       memset (&threadpool_io->updates, 0, UPDATES_CAPACITY * sizeof (ThreadPoolIOUpdate));
                }
+
+               mono_mutex_unlock (&threadpool_io->updates_lock);
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wai");
+
+               res = threadpool_io->backend.event_wait (wait_callback, states);
+
+               if (res == -1 || mono_runtime_is_shutting_down ())
+                       break;
        }
 
-       mono_mutex_unlock (&threadpool_io->lock);
+       mono_g_hash_table_destroy (states);
 
        io_selector_running = FALSE;
 }
 
+/* Locking: threadpool_io->updates_lock must be held */
+static ThreadPoolIOUpdate*
+update_get_new (void)
+{
+       ThreadPoolIOUpdate *update = NULL;
+       g_assert (threadpool_io->updates_size <= UPDATES_CAPACITY);
+
+       while (threadpool_io->updates_size == UPDATES_CAPACITY) {
+               /* we wait for updates to be applied in the selector_thread and we loop
+                * as long as none are available. if it happends too much, then we need
+                * to increase UPDATES_CAPACITY */
+               mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
+       }
+
+       g_assert (threadpool_io->updates_size < UPDATES_CAPACITY);
+
+       update = &threadpool_io->updates [threadpool_io->updates_size ++];
+
+       return update;
+}
+
 static void
 wakeup_pipes_init (void)
 {
@@ -460,26 +529,20 @@ initialize (void)
        threadpool_io = g_new0 (ThreadPoolIO, 1);
        g_assert (threadpool_io);
 
-       mono_mutex_init_recursive (&threadpool_io->lock);
-
-       mono_cond_init (&threadpool_io->updates_signal, NULL);
+       mono_mutex_init_recursive (&threadpool_io->updates_lock);
+       mono_cond_init (&threadpool_io->updates_cond, NULL);
+       mono_gc_register_root ((void*)&threadpool_io->updates [0], sizeof (threadpool_io->updates), MONO_GC_DESCRIPTOR_NULL);
 
-       threadpool_io->states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC);
-       MONO_GC_REGISTER_ROOT_FIXED (threadpool_io->states);
-
-       threadpool_io->updates = NULL;
        threadpool_io->updates_size = 0;
-       threadpool_io->updates_capacity = 0;
 
+       threadpool_io->backend = backend_poll;
+       if (g_getenv ("MONO_ENABLE_AIO") != NULL) {
 #if defined(HAVE_EPOLL)
-       threadpool_io->backend = backend_epoll;
+               threadpool_io->backend = backend_epoll;
 #elif defined(HAVE_KQUEUE)
-       threadpool_io->backend = backend_kqueue;
-#else
-       threadpool_io->backend = backend_poll;
+               threadpool_io->backend = backend_kqueue;
 #endif
-       if (g_getenv ("MONO_DISABLE_AIO") != NULL)
-               threadpool_io->backend = backend_poll;
+       }
 
        wakeup_pipes_init ();
 
@@ -501,15 +564,8 @@ cleanup (void)
        while (io_selector_running)
                g_usleep (1000);
 
-       mono_mutex_destroy (&threadpool_io->lock);
-
-       mono_cond_destroy (&threadpool_io->updates_signal);
-
-       MONO_GC_UNREGISTER_ROOT (threadpool_io->states);
-       mono_g_hash_table_destroy (threadpool_io->states);
-
-       if (threadpool_io->updates)
-               mono_gc_free_fixed (threadpool_io->updates);
+       mono_mutex_destroy (&threadpool_io->updates_lock);
+       mono_cond_destroy (&threadpool_io->updates_cond);
 
        threadpool_io->backend.cleanup ();
 
@@ -533,7 +589,6 @@ is_socket_async_callback (MonoImage *system_image, MonoClass *class)
        MonoClass *socket_async_callback_class = NULL;
 
        socket_async_callback_class = mono_class_from_name (system_image, "System.Net.Sockets", "SocketAsyncCallback");
-       g_assert (socket_async_callback_class);
 
        return class == socket_async_callback_class;
 }
@@ -544,7 +599,6 @@ is_async_read_handler (MonoImage *system_image, MonoClass *class)
        MonoClass *async_read_handler_class = NULL;
 
        async_read_handler_class = mono_class_from_name (system_image, "System.Diagnostics", "Process/AsyncReadHandler");
-       g_assert (async_read_handler_class);
 
        return class == async_read_handler_class;
 }
@@ -578,111 +632,77 @@ mono_threadpool_ms_io_cleanup (void)
 MonoAsyncResult *
 mono_threadpool_ms_io_add (MonoAsyncResult *ares, MonoSocketAsyncResult *sockares)
 {
+       ThreadPoolIOUpdate *update;
+
        g_assert (ares);
        g_assert (sockares);
 
        if (mono_runtime_is_shutting_down ())
                return NULL;
+       if (mono_domain_is_unloading (mono_object_domain (sockares)))
+               return NULL;
 
        mono_lazy_initialize (&io_status, initialize);
 
        MONO_OBJECT_SETREF (sockares, ares, ares);
 
-       update_add (GPOINTER_TO_INT (sockares->handle), sockares);
+       mono_mutex_lock (&threadpool_io->updates_lock);
 
-       return ares;
-}
+       update = update_get_new ();
+       update->type = UPDATE_ADD;
+       update->data.add.fd = GPOINTER_TO_INT (sockares->handle);
+       update->data.add.sockares = sockares;
+       mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */
 
-static gboolean
-remove_update_for_socket (ThreadPoolIOUpdate *update, gpointer user_data)
-{
-       if (!update->sockares)
-               return FALSE;
+       selector_thread_wakeup ();
+
+       mono_mutex_unlock (&threadpool_io->updates_lock);
 
-       return GPOINTER_TO_INT (update->sockares->handle) == GPOINTER_TO_INT (user_data);
+       return ares;
 }
 
 void
 mono_threadpool_ms_io_remove_socket (int fd)
 {
-       MonoMList *list = NULL;
-       gpointer k;
+       ThreadPoolIOUpdate *update;
 
        if (!mono_lazy_is_initialized (&io_status))
                return;
 
-       mono_mutex_lock (&threadpool_io->lock);
-
-       g_assert (threadpool_io->states);
-
-       if (mono_g_hash_table_lookup_extended (threadpool_io->states, GINT_TO_POINTER (fd), &k, (gpointer*) &list))
-               mono_g_hash_table_remove (threadpool_io->states, GINT_TO_POINTER (fd));
-
-       update_remove (remove_update_for_socket, GINT_TO_POINTER (fd));
-
-       mono_mutex_unlock (&threadpool_io->lock);
+       mono_mutex_lock (&threadpool_io->updates_lock);
 
-       for (; list; list = mono_mlist_remove_item (list, list)) {
-               MonoSocketAsyncResult *sockares = (MonoSocketAsyncResult*) mono_mlist_get_data (list);
+       update = update_get_new ();
+       update->type = UPDATE_REMOVE_SOCKET;
+       update->data.add.fd = fd;
+       mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */
 
-               if (!sockares)
-                       continue;
-
-               switch (sockares->operation) {
-               case AIO_OP_RECEIVE:
-                       sockares->operation = AIO_OP_RECV_JUST_CALLBACK;
-                       break;
-               case AIO_OP_SEND:
-                       sockares->operation = AIO_OP_SEND_JUST_CALLBACK;
-                       break;
-               }
-
-               mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
-       }
-
-       update_add (fd, NULL);
-}
-
-static gboolean
-remove_sockstate_for_domain (gpointer key, gpointer value, gpointer user_data)
-{
-       MonoMList *list;
-       gboolean remove = FALSE;
-
-       for (list = value; list; list = mono_mlist_next (list)) {
-               MonoObject *data = mono_mlist_get_data (list);
-               if (mono_object_domain (data) == user_data) {
-                       remove = TRUE;
-                       mono_mlist_set_data (list, NULL);
-               }
-       }
+       selector_thread_wakeup ();
 
-       //FIXME is there some sort of additional unregistration we need to perform here?
-       return remove;
-}
+       mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
 
-static gboolean
-remove_update_for_domain (ThreadPoolIOUpdate *update, gpointer user_data)
-{
-       if (!update->sockares)
-               return FALSE;
-
-       return mono_object_domain (update->sockares) == (MonoDomain*) user_data;
+       mono_mutex_unlock (&threadpool_io->updates_lock);
 }
 
 void
 mono_threadpool_ms_io_remove_domain_jobs (MonoDomain *domain)
 {
+       ThreadPoolIOUpdate *update;
+
        if (!mono_lazy_is_initialized (&io_status))
                return;
 
-       mono_mutex_lock (&threadpool_io->lock);
+       mono_mutex_lock (&threadpool_io->updates_lock);
 
-       mono_g_hash_table_foreach_remove (threadpool_io->states, remove_sockstate_for_domain, domain);
+       update = update_get_new ();
+       update->type = UPDATE_REMOVE_DOMAIN;
+       update->data.remove_domain.domain = domain;
+       mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */
+
+       selector_thread_wakeup ();
 
-       update_remove (remove_update_for_domain, domain);
+       mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
 
-       mono_mutex_unlock (&threadpool_io->lock);
+       mono_mutex_unlock (&threadpool_io->updates_lock);
 }
 
 void
index c1eb63b2d15529300d08faa91d79f246ff556d56..d5e388d1e28186ec210c79788ea9f43bda0361e2 100644 (file)
@@ -315,10 +315,14 @@ cleanup (void)
         * cleaning up only if the runtime is shutting down */
        g_assert (mono_runtime_is_shutting_down ());
 
+       MONO_PREPARE_BLOCKING;
        while (monitor_status != MONITOR_STATUS_NOT_RUNNING)
                g_usleep (1000);
+       MONO_FINISH_BLOCKING;
 
+       MONO_PREPARE_BLOCKING;
        mono_mutex_lock (&threadpool->active_threads_lock);
+       MONO_FINISH_BLOCKING;
 
        /* stop all threadpool->working_threads */
        for (i = 0; i < threadpool->working_threads->len; ++i)
@@ -492,6 +496,8 @@ worker_park (void)
 
        mono_gc_set_skip_thread (TRUE);
 
+       MONO_PREPARE_BLOCKING;
+
        mono_mutex_lock (&threadpool->active_threads_lock);
 
        if (!mono_runtime_is_shutting_down ()) {
@@ -506,6 +512,8 @@ worker_park (void)
 
        mono_mutex_unlock (&threadpool->active_threads_lock);
 
+       MONO_FINISH_BLOCKING;
+
        mono_gc_set_skip_thread (FALSE);
 
        mono_cond_destroy (&cond);
@@ -521,6 +529,8 @@ worker_try_unpark (void)
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try unpark worker", GetCurrentThreadId ());
 
+       MONO_PREPARE_BLOCKING;
+
        mono_mutex_lock (&threadpool->active_threads_lock);
        len = threadpool->parked_threads->len;
        if (len > 0) {
@@ -530,6 +540,8 @@ worker_try_unpark (void)
        }
        mono_mutex_unlock (&threadpool->active_threads_lock);
 
+       MONO_FINISH_BLOCKING;
+
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try unpark worker, success? %s", GetCurrentThreadId (), res ? "yes" : "no");
 
        return res;
@@ -567,9 +579,11 @@ worker_thread (gpointer data)
 
        mono_thread_set_name_internal (thread, mono_string_new (mono_domain_get (), "Threadpool worker"), FALSE);
 
+       MONO_PREPARE_BLOCKING;
        mono_mutex_lock (&threadpool->active_threads_lock);
        g_ptr_array_add (threadpool->working_threads, thread);
        mono_mutex_unlock (&threadpool->active_threads_lock);
+       MONO_FINISH_BLOCKING;
 
        previous_tpdomain = NULL;
 
@@ -653,9 +667,11 @@ worker_thread (gpointer data)
 
        mono_mutex_unlock (&threadpool->domains_lock);
 
+       MONO_PREPARE_BLOCKING;
        mono_mutex_lock (&threadpool->active_threads_lock);
        g_ptr_array_remove_fast (threadpool->working_threads, thread);
        mono_mutex_unlock (&threadpool->active_threads_lock);
+       MONO_FINISH_BLOCKING;
 
        COUNTER_ATOMIC (counter, {
                counter._.working--;
@@ -848,6 +864,7 @@ monitor_thread (void)
                if (mono_runtime_is_shutting_down () || !domain_any_has_request ())
                        continue;
 
+               MONO_PREPARE_BLOCKING;
                mono_mutex_lock (&threadpool->active_threads_lock);
                for (i = 0; i < threadpool->working_threads->len; ++i) {
                        thread = g_ptr_array_index (threadpool->working_threads, i);
@@ -857,6 +874,7 @@ monitor_thread (void)
                        }
                }
                mono_mutex_unlock (&threadpool->active_threads_lock);
+               MONO_FINISH_BLOCKING;
 
                if (all_waitsleepjoin) {
                        ThreadPoolCounter counter;
@@ -1304,7 +1322,7 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
                return NULL;
        }
 
-       MONO_OBJECT_SETREF (ares, endinvoke_called, 1);
+       ares->endinvoke_called = 1;
 
        /* wait until we are really finished */
        if (ares->completed) {
@@ -1319,9 +1337,9 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
                        MONO_OBJECT_SETREF (ares, handle, (MonoObject*) mono_wait_handle_new (mono_object_domain (ares), wait_event));
                }
                mono_monitor_exit ((MonoObject*) ares);
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
        }
 
        ac = (MonoAsyncCall*) ares->object_data;
@@ -1370,9 +1388,9 @@ mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
        mono_memory_write_barrier ();
 
        while (domain->threadpool_jobs) {
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                WaitForSingleObject (sem, timeout);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
                if (timeout != -1) {
                        timeout -= mono_msec_ticks () - start;
                        if (timeout <= 0) {
index 3a4e53eb5a231af2ac1810d03fca8f933d561ddb..28903fe586e140104cba982de25de8e62443d0ad 100644 (file)
@@ -228,13 +228,12 @@ static gboolean shutting_down = FALSE;
 
 static gint32 managed_thread_id_counter = 0;
 
-
 static void
 mono_threads_lock (void)
 {
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_locks_acquire (&threads_mutex, ThreadsLock);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 }
 
 static void
@@ -379,9 +378,9 @@ lock_thread (MonoInternalThread *thread)
 
        g_assert (thread->synch_cs);
 
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (thread->synch_cs);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 }
 
 static inline void
@@ -453,7 +452,7 @@ static void thread_cleanup (MonoInternalThread *thread)
                }
                /* This needs to be called even if handle_remove () fails */
                if (mono_thread_cleanup_fn)
-                       mono_thread_cleanup_fn ((MonoNativeThreadId)thread->tid);
+                       mono_thread_cleanup_fn (thread_get_tid (thread));
                return;
        }
        mono_release_type_locks (thread);
@@ -480,7 +479,7 @@ static void thread_cleanup (MonoInternalThread *thread)
        thread->appdomain_refs = NULL;
 
        if (mono_thread_cleanup_fn)
-               mono_thread_cleanup_fn ((MonoNativeThreadId)thread->tid);
+               mono_thread_cleanup_fn (thread_get_tid (thread));
 
        if (mono_gc_is_moving ()) {
                MONO_GC_UNREGISTER_ROOT (thread->thread_pinning_ref);
@@ -650,7 +649,7 @@ static guint32 WINAPI start_wrapper_internal(void *data)
        internal->thread_info = info;
        internal->small_id = info->small_id;
 
-       tid=internal->tid;
+       tid = internal->tid;
 
        SET_CURRENT_OBJECT (internal);
 
@@ -804,7 +803,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
         */
        if (thread_start_args == NULL) {
                MONO_GC_REGISTER_ROOT_FIXED (thread_start_args);
-               thread_start_args = mono_g_hash_table_new (NULL, NULL);
+               thread_start_args = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_CONSERVATIVE_GC);
        }
        mono_g_hash_table_insert (thread_start_args, thread, start_info->start_arg);
        if (threads_starting_up == NULL) {
@@ -832,10 +831,10 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
         */
        create_flags = CREATE_SUSPENDED;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)start_wrapper, start_info,
                                                                                                stack_size, create_flags, &tid);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (thread_handle == NULL) {
                /* The thread couldn't be created, so throw an exception */
@@ -867,9 +866,9 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
        if (!handle_store (thread, FALSE))
                return FALSE;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        mono_thread_info_resume (tid);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (internal->start_notify) {
                /*
@@ -880,9 +879,9 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
                 */
                THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, GetCurrentThreadId (), internal, (gsize)internal->tid));
 
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
 
                CloseHandle (internal->start_notify);
                internal->start_notify = NULL;
@@ -981,8 +980,8 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 
        tid=GetCurrentThreadId ();
 
-       thread->handle=thread_handle;
-       thread->tid=tid;
+       thread->handle = thread_handle;
+       thread->tid = tid;
        thread->stack_ptr = &tid;
 
        THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
@@ -1194,9 +1193,9 @@ ves_icall_System_Threading_Thread_Sleep_internal(gint32 ms)
        while (TRUE) {
                mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                res = SleepEx(ms,TRUE);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
        
                mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
@@ -1412,9 +1411,9 @@ ves_icall_System_Threading_Thread_Join_internal(MonoThread *this_obj, int ms)
        
        mono_thread_set_state (cur_thread, ThreadState_WaitSleepJoin);
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret=WaitForSingleObjectEx (handle, ms, TRUE);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        mono_thread_clr_state (cur_thread, ThreadState_WaitSleepJoin);
        
@@ -1440,12 +1439,12 @@ mono_wait_uninterrupted (MonoInternalThread *thread, gboolean multiple, guint32
 
        start = (ms == -1) ? 0 : mono_100ns_ticks ();
        do {
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                        if (multiple)
                        ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable);
                else
                        ret = WaitForSingleObjectEx (handles [0], ms, alertable);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
 
                if (ret != WAIT_IO_COMPLETION)
                        break;
@@ -1606,9 +1605,9 @@ ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, H
 
        mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret = SignalObjectAndWait (toSignal, toWait, ms, TRUE);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
@@ -2709,9 +2708,9 @@ static void wait_for_tids (struct wait_data *wait, guint32 timeout)
        
        THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==WAIT_FAILED) {
                /* See the comment in build_wait_tids() */
@@ -2772,9 +2771,9 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
                count++;
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if(ret==WAIT_FAILED) {
                /* See the comment in build_wait_tids() */
@@ -2836,7 +2835,7 @@ static void build_wait_tids (gpointer key, gpointer value, gpointer user)
                        return;
                }
 
-               handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+               handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                if (handle == NULL) {
                        THREAD_DEBUG (g_message ("%s: ignoring unopenable thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
                        return;
@@ -2876,7 +2875,7 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
        if (thread->tid != self && (thread->state & ThreadState_Background) != 0 &&
                !(thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)) {
        
-               handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+               handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                if (handle == NULL)
                        return FALSE;
 
@@ -3058,7 +3057,7 @@ collect_threads_for_suspend (gpointer key, gpointer value, gpointer user_data)
                return;
 
        if (wait->num<MAXIMUM_WAIT_OBJECTS) {
-               handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+               handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                if (handle == NULL)
                        return;
 
@@ -3180,7 +3179,7 @@ print_stack_frame_to_string (MonoStackFrameInfo *frame, MonoContext *ctx, gpoint
 {
        GString *p = (GString*)data;
        MonoMethod *method = NULL;
-       if (frame->ji)
+       if (frame->type == FRAME_TYPE_MANAGED)
                method = mono_jit_info_get_method (frame->ji);
 
        if (method) {
@@ -3249,7 +3248,7 @@ dump_thread (gpointer key, gpointer value, gpointer user)
        We probably should loop a bit around trying to get it to either managed code
        or WSJ state.
        */
-       mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gsize)thread->tid, FALSE, print_thread_dump, thread);
+       mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), FALSE, print_thread_dump, thread);
 }
 
 void
@@ -3425,7 +3424,7 @@ collect_appdomain_thread (gpointer key, gpointer value, gpointer user_data)
                /* printf ("ABORTING THREAD %p BECAUSE IT REFERENCES DOMAIN %s.\n", thread->tid, domain->friendly_name); */
 
                if(data->wait.num<MAXIMUM_WAIT_OBJECTS) {
-                       HANDLE handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+                       HANDLE handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                        if (handle == NULL)
                                return;
                        data->wait.handles [data->wait.num] = handle;
@@ -4028,8 +4027,9 @@ mono_thread_execute_interruption (MonoInternalThread *thread)
                WaitForSingleObjectEx (GetCurrentThread(), 0, TRUE);
 #endif
                InterlockedDecrement (&thread_interruption_requested);
+
                /* Clear the interrupted flag of the thread so it can wait again */
-               mono_thread_info_clear_interruption ();
+               mono_thread_info_clear_self_interrupt ();
        }
 
        if ((thread->state & ThreadState_AbortRequested) != 0) {
@@ -4399,7 +4399,7 @@ mono_thread_info_get_last_managed (MonoThreadInfo *info)
 typedef struct {
        MonoInternalThread *thread;
        gboolean install_async_abort;
-       gpointer interrupt_handle;
+       MonoThreadInfoInterruptToken *interrupt_token;
 } AbortThreadData;
 
 static SuspendThreadResult
@@ -4421,7 +4421,7 @@ abort_thread_critical (MonoThreadInfo *info, gpointer ud)
        InterlockedIncrement (&thread_interruption_requested);
 
        ji = mono_thread_info_get_last_managed (info);
-       protected_wrapper = ji && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
+       protected_wrapper = ji && !ji->is_trampoline && !ji->async && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
        running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
 
        if (!protected_wrapper && running_managed) {
@@ -4442,7 +4442,8 @@ abort_thread_critical (MonoThreadInfo *info, gpointer ud)
                 * functions in the io-layer until the signal handler calls QueueUserAPC which will
                 * make it return.
                 */
-               data->interrupt_handle = mono_thread_info_prepare_interrupt (thread->handle);
+               data->interrupt_token = mono_thread_info_prepare_interrupt (info);
+
                return MonoResumeThread;
        }
 }
@@ -4463,20 +4464,22 @@ abort_thread_internal (MonoInternalThread *thread, gboolean can_raise_exception,
                MonoException *exc = mono_thread_request_interruption (can_raise_exception); 
                if (exc)
                        mono_raise_exception (exc);
-               mono_thread_info_interrupt (thread->handle);
+
+               mono_thread_info_self_interrupt ();
+
                return;
        }
 
-       mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gsize)thread->tid, TRUE, abort_thread_critical, &data);
-       if (data.interrupt_handle)
-               mono_thread_info_finish_interrupt (data.interrupt_handle);
+       mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), TRUE, abort_thread_critical, &data);
+       if (data.interrupt_token)
+               mono_thread_info_finish_interrupt (data.interrupt_token);
        /*FIXME we need to wait for interruption to complete -- figure out how much into interruption we should wait for here*/
 }
 
 typedef struct{
        MonoInternalThread *thread;
        gboolean interrupt;
-       gpointer interrupt_handle;
+       MonoThreadInfoInterruptToken *interrupt_token;
 } SuspendThreadData;
 
 static SuspendThreadResult
@@ -4489,7 +4492,7 @@ suspend_thread_critical (MonoThreadInfo *info, gpointer ud)
        gboolean running_managed;
 
        ji = mono_thread_info_get_last_managed (info);
-       protected_wrapper = ji && !ji->async && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
+       protected_wrapper = ji && !ji->is_trampoline && !ji->async && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
        running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
 
        if (running_managed && !protected_wrapper) {
@@ -4500,7 +4503,7 @@ suspend_thread_critical (MonoThreadInfo *info, gpointer ud)
                if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 0)
                        InterlockedIncrement (&thread_interruption_requested);
                if (data->interrupt)
-                       data->interrupt_handle = mono_thread_info_prepare_interrupt (thread->handle);
+                       data->interrupt_token = mono_thread_info_prepare_interrupt (thread->thread_info);
                
                if (mono_thread_notify_pending_exc_fn && !running_managed)
                        /* The JIT will notify the thread about the interruption */
@@ -4525,9 +4528,9 @@ suspend_thread_internal (MonoInternalThread *thread, gboolean interrupt)
                data.thread = thread;
                data.interrupt = interrupt;
 
-               mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gsize)thread->tid, interrupt, suspend_thread_critical, &data);
-               if (data.interrupt_handle)
-                       mono_thread_info_finish_interrupt (data.interrupt_handle);
+               mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), interrupt, suspend_thread_critical, &data);
+               if (data.interrupt_token)
+                       mono_thread_info_finish_interrupt (data.interrupt_token);
                UNLOCK_THREAD (thread);
        }
 }
@@ -4549,7 +4552,7 @@ resume_thread_internal (MonoInternalThread *thread)
 {
        UNLOCK_THREAD (thread);
        /* Awake the thread */
-       if (!mono_thread_info_resume ((MonoNativeThreadId)(gpointer)(gsize)thread->tid))
+       if (!mono_thread_info_resume (thread_get_tid (thread)))
                return FALSE;
        LOCK_THREAD (thread);
        thread->state &= ~ThreadState_Suspended;
index ee02ad4f7becedc289f30935906466e8edc32827..cb409a9fedc9b02a439fc3a5c8109f453f730241 100755 (executable)
@@ -6,7 +6,7 @@ monodir=$(top_builddir)
 libgc_libs=$(monodir)/libgc/libmonogc.la
 libgc_static_libs=$(monodir)/libgc/libmonogc-static.la
 
-libs=  \
+boehm_libs=    \
        $(monodir)/mono/metadata/libmonoruntime.la      \
        $(monodir)/mono/io-layer/libwapi.la     \
        $(monodir)/mono/utils/libmonoutils.la \
@@ -20,14 +20,14 @@ sgen_libs = \
        $(monodir)/mono/utils/libmonoutils.la \
        $(GLIB_LIBS) $(LIBICONV)
 
-static_libs=   \
+boehm_static_libs=     \
        $(monodir)/mono/metadata/libmonoruntime-static.la       \
        $(monodir)/mono/io-layer/libwapi.la     \
        $(monodir)/mono/utils/libmonoutils.la \
        $(GLIB_LIBS) $(LIBICONV) \
        $(libgc_static_libs)
 
-sgenstatic_libs = \
+sgen_static_libs = \
        $(monodir)/mono/metadata/libmonoruntimesgen-static.la   \
        $(monodir)/mono/sgen/libmonosgen-static.la      \
        $(monodir)/mono/io-layer/libwapi.la     \
@@ -78,16 +78,16 @@ endif
 if SUPPORT_SGEN
 sgen_binaries = mono-sgen
 sgen_libraries = libmonosgen-2.0.la
-sgen_static_libraries = libmini-static.la $(sgenstatic_libs)
+sgen_static_libraries = libmini-static.la $(sgen_static_libs)
 endif
 
 if SUPPORT_BOEHM
 boehm_libraries = libmonoboehm-2.0.la
-boehm_static_libraries = libmini-static.la $(static_libs)
+boehm_static_libraries = libmini-static.la $(boehm_static_libs)
 boehm_binaries  = mono-boehm
 endif
 
-#The mono uses sgen, while libmono remains boehm
+# The mono executable uses sgen, while libmono remains boehm
 if SUPPORT_SGEN
 mono_bin_suffix = sgen
 else
@@ -152,7 +152,7 @@ libmono_llvm_la_LIBADD = $(GLIB_LIBS) $(LLVM_LIBS) $(LLVM_LDFLAGS)
 if PLATFORM_DARWIN
 libmono_llvm_la_LDFLAGS=-Wl,-undefined -Wl,suppress -Wl,-flat_namespace
 else
-libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $(libs)
+libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $(boehm_libs)
 endif
 endif
 
@@ -541,7 +541,7 @@ libmini_la_CFLAGS = $(mono_CFLAGS)
 
 libmonoboehm_2_0_la_SOURCES =
 libmonoboehm_2_0_la_CFLAGS = $(mono_boehm_CFLAGS)
-libmonoboehm_2_0_la_LIBADD = libmini.la $(libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
+libmonoboehm_2_0_la_LIBADD = libmini.la $(boehm_libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
 libmonoboehm_2_0_la_LDFLAGS = $(libmonoldflags)
 
 libmonosgen_2_0_la_SOURCES =
@@ -649,13 +649,12 @@ checktests: $(regtests)
 rcheck: mono $(regtests)
 if NACL_CODEGEN
        for i in $(regtests); do echo "running test $$i"; $(MINI_RUNTIME) $$i --exclude 'NaClDisable' || exit 1; done
-else
+elif JENKINS_URL
        -($(MINI_RUNTIME) --regression $(regtests); echo $$? > regressionexitcode.out) | $(srcdir)/emitnunit.pl
        exit $$(cat regressionexitcode.out)
-endif
-
-rcheck2: mono $(regtests)
+else
        $(MINI_RUNTIME) --regression $(regtests)
+endif
 
 check-seq-points: mono $(regtests)
        rm -f TestResults_op_il_seq_point.xml
@@ -683,16 +682,36 @@ gsharedvtcheck:
 
 fullaot_regtests = $(regtests) aot-tests.exe $(if $(GSHAREDVT),gshared.exe)
 
+FULLAOT_LIBS = \
+       mscorlib.dll \
+       System.Core.dll \
+       System.dll \
+       Mono.Posix.dll \
+       System.Configuration.dll \
+       System.Security.dll \
+       System.Xml.dll \
+       Mono.Security.dll \
+       Mono.Simd.dll
+
 # This currently only works on amd64/arm
 fullaotcheck: mono $(fullaot_regtests)
        rm -rf fullaot-tmp
        mkdir fullaot-tmp
-       cp $(CLASS)/mscorlib.dll $(CLASS)/System.Core.dll $(CLASS)/System.dll $(CLASS)/Mono.Posix.dll $(CLASS)/System.Configuration.dll $(CLASS)/System.Security.dll $(CLASS)/System.Xml.dll $(CLASS)/Mono.Security.dll $(CLASS)/Mono.Simd.dll $(regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
-       cp $(fullaot_regtests) fullaot-tmp/
-       MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot=full fullaot-tmp/* || exit 1
+       $(MAKE) fullaot-libs AOT_FLAGS=full
+       cp $(regtests) $(fullaot_regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
+       MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot=full fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
        ln -s $$PWD/mono fullaot-tmp/
        for i in $(fullaot_regtests); do echo $$i; MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper --full-aot fullaot-tmp/$$i --exclude '!FULLAOT' $(ARCH_FULLAOT_EXCLUDE) || exit 1; done
 
+# This can run in parallel
+fullaot-libs: $(patsubst %,fullaot-tmp/%.dylib,$(FULLAOT_LIBS))
+
+fullaot-tmp/%.dylib: $(CLASS)/%
+       cp $(CLASS)/$* fullaot-tmp/
+       mkdir fullaot-tmp/$*-tmp
+       MONO_PATH=fullaot-tmp/:$(CLASS) $(top_builddir)/runtime/mono-wrapper --aot=$(AOT_FLAGS),temp-path=fullaot-tmp/$*-tmp fullaot-tmp/$*
+       rm -rf fullaot-tmp/$*-tmp
+
 llvmfullaotcheck:
        $(MAKE) fullaotcheck LLVM=1
 
index c9e50793c1d52795125a5ae35a622c9872556d39..0e5fac63d80cdb7e06b32a517892f5890a19e9db 100644 (file)
@@ -42,7 +42,6 @@
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/gc-internal.h>
-#include <mono/metadata/monitor.h>
 #include <mono/metadata/mempool-internals.h>
 #include <mono/metadata/mono-endian.h>
 #include <mono/metadata/threads-types.h>
@@ -298,6 +297,9 @@ get_patch_name (int info)
 
 #endif
 
+static guint32
+get_unwind_info_offset (MonoAotCompile *acfg, guint8 *encoded, guint32 encoded_len);
+
 static char*
 get_plt_entry_debug_sym (MonoAotCompile *acfg, MonoJumpInfo *ji, GHashTable *cache);
 
@@ -1196,6 +1198,22 @@ arch_emit_llvm_plt_entry (MonoAotCompile *acfg, const char *got_symbol, int offs
 #endif
 }
 
+/* Save unwind_info in the module and emit the offset to the information at symbol */
+static void save_unwind_info (MonoAotCompile *acfg, char *symbol, GSList *unwind_ops)
+{
+       guint32 uw_offset, encoded_len;
+       guint8 *encoded;
+
+       emit_section_change (acfg, RODATA_SECT, 0);
+       emit_global (acfg, symbol, FALSE);
+       emit_label (acfg, symbol);
+
+       encoded = mono_unwind_ops_encode (unwind_ops, &encoded_len);
+       uw_offset = get_unwind_info_offset (acfg, encoded, encoded_len);
+       g_free (encoded);
+       emit_int32 (acfg, uw_offset);
+}
+
 /*
  * arch_emit_specific_trampoline_pages:
  *
@@ -1219,6 +1237,7 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg)
        guint8 *loop_start, *loop_branch_back, *loop_end_check, *imt_found_check;
        int i;
        int pagesize = MONO_AOT_TRAMP_PAGE_SIZE;
+       GSList *unwind_ops = NULL;
 #define COMMON_TRAMP_SIZE 16
        int count = (pagesize - COMMON_TRAMP_SIZE) / 8;
        int imm8, rot_amount;
@@ -1311,7 +1330,6 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg)
        /* now the imt trampolines: each specific trampolines puts in the ip register
         * the instruction pointer address, so the generic trampoline at the start of the page
         * subtracts 4096 to get to the data page and loads the values
-        * We again fit the generic trampiline in 16 bytes.
         */
 #define IMT_TRAMP_SIZE 72
        sprintf (symbol, "%simt_trampolines_page", acfg->user_symbol_prefix);
@@ -1377,6 +1395,53 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg)
        acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_STATIC_RGCTX] = 16;
        acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_IMT_THUNK] = 72;
        acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_GSHAREDVT_ARG] = 16;
+
+       /* Unwind info for specifc trampolines */
+       sprintf (symbol, "%sspecific_trampolines_page_gen_p", acfg->user_symbol_prefix);
+       /* We unwind to the original caller, from the stack, since lr is clobbered */
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 14 * sizeof (mgreg_t));
+       mono_add_unwind_op_offset (unwind_ops, 0, 0, ARMREG_LR, -4);
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
+
+       sprintf (symbol, "%sspecific_trampolines_page_sp_p", acfg->user_symbol_prefix);
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, 4, 0, 14 * sizeof (mgreg_t));
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
+
+       /* Unwind info for rgctx trampolines */
+       sprintf (symbol, "%srgctx_trampolines_page_gen_p", acfg->user_symbol_prefix);
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+       save_unwind_info (acfg, symbol, unwind_ops);
+
+       sprintf (symbol, "%srgctx_trampolines_page_sp_p", acfg->user_symbol_prefix);
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
+
+       /* Unwind info for gsharedvt trampolines */
+       sprintf (symbol, "%sgsharedvt_trampolines_page_gen_p", acfg->user_symbol_prefix);
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, 4, 0, 4 * sizeof (mgreg_t));
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
+
+       sprintf (symbol, "%sgsharedvt_trampolines_page_sp_p", acfg->user_symbol_prefix);
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
+
+       /* Unwind info for imt trampolines */
+       sprintf (symbol, "%simt_trampolines_page_gen_p", acfg->user_symbol_prefix);
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, 4, 0, 3 * sizeof (mgreg_t));
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
+
+       sprintf (symbol, "%simt_trampolines_page_sp_p", acfg->user_symbol_prefix);
+       mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+       save_unwind_info (acfg, symbol, unwind_ops);
+       mono_free_unwind_info (unwind_ops);
 #elif defined(TARGET_ARM64)
        arm64_emit_specific_trampoline_pages (acfg);
 #endif
@@ -1546,14 +1611,6 @@ arch_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size
 
        /* FIXME: Could this clobber the register needed by get_vcall_slot () ? */
 
-       /* We clobber ECX, since EAX is used as MONO_ARCH_MONITOR_OBJECT_REG */
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-       g_assert (MONO_ARCH_MONITOR_OBJECT_REG != X86_ECX);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
-       g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG != X86_ECX);
-#endif
-#endif
-
        code = buf;
        /* Load mscorlib got address */
        x86_mov_reg_membase (code, X86_ECX, MONO_ARCH_GOT_REG, sizeof (gpointer), 4);
@@ -3138,9 +3195,6 @@ is_plt_patch (MonoJumpInfo *patch_info)
        case MONO_PATCH_INFO_JIT_ICALL_ADDR:
        case MONO_PATCH_INFO_ICALL_ADDR:
        case MONO_PATCH_INFO_RGCTX_FETCH:
-       case MONO_PATCH_INFO_MONITOR_ENTER:
-       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
-       case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
                return TRUE;
        default:
@@ -5372,9 +5426,6 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
                encode_patch (acfg, entry->data, p, &p);
                break;
        }
-       case MONO_PATCH_INFO_MONITOR_ENTER:
-       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
-       case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_SEQ_POINT_INFO:
                break;
        case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
@@ -6194,7 +6245,7 @@ emit_trampoline_full (MonoAotCompile *acfg, int got_offset, MonoTrampInfo *info,
 static G_GNUC_UNUSED void
 emit_trampoline (MonoAotCompile *acfg, int got_offset, MonoTrampInfo *info)
 {
-       emit_trampoline_full (acfg, got_offset, info, FALSE);
+       emit_trampoline_full (acfg, got_offset, info, TRUE);
 }
 
 static void
@@ -6239,17 +6290,6 @@ emit_trampolines (MonoAotCompile *acfg)
                        emit_trampoline (acfg, acfg->got_offset, info);
                }
 
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG)
-               mono_arch_create_monitor_enter_trampoline (&info, FALSE, TRUE);
-               emit_trampoline (acfg, acfg->got_offset, info);
-#if defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
-               mono_arch_create_monitor_enter_trampoline (&info, TRUE, TRUE);
-               emit_trampoline (acfg, acfg->got_offset, info);
-#endif
-               mono_arch_create_monitor_exit_trampoline (&info, TRUE);
-               emit_trampoline (acfg, acfg->got_offset, info);
-#endif
-
                /* Emit the exception related code pieces */
                mono_arch_get_restore_context (&info, TRUE);
                emit_trampoline (acfg, acfg->got_offset, info);
@@ -7543,6 +7583,7 @@ static void
 emit_code (MonoAotCompile *acfg)
 {
        int oindex, i, prev_index;
+       gboolean saved_unbox_info = FALSE;
        char symbol [256];
 
 #if defined(TARGET_POWERPC64)
@@ -7610,6 +7651,23 @@ emit_code (MonoAotCompile *acfg)
 
                        if (acfg->thumb_mixed && cfg->compile_llvm)
                                emit_set_arm_mode (acfg);
+
+                       if (!saved_unbox_info) {
+                               char user_symbol [128];
+                               GSList *unwind_ops;
+                               sprintf (user_symbol, "%sunbox_trampoline_p", acfg->user_symbol_prefix);
+
+                               emit_label (acfg, "ut_end");
+
+                               unwind_ops = mono_unwind_get_cie_program ();
+                               save_unwind_info (acfg, user_symbol, unwind_ops);
+                               mono_free_unwind_info (unwind_ops);
+
+                               /* Save the unbox trampoline size */
+                               emit_symbol_diff (acfg, "ut_end", symbol, 0);
+
+                               saved_unbox_info = TRUE;
+                       }
                }
 
                if (cfg->compile_llvm)
@@ -9137,7 +9195,7 @@ compile_asm (MonoAotCompile *acfg)
        tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name);
 
        if (acfg->llvm) {
-               llvm_ofile = g_strdup (acfg->llvm_ofile);
+               llvm_ofile = g_strdup_printf ("\"%s\"", acfg->llvm_ofile);
        } else {
                llvm_ofile = g_strdup ("");
        }
@@ -9146,7 +9204,7 @@ compile_asm (MonoAotCompile *acfg)
        g_strdelimit (ld_flags, ";", ' ');
 
 #ifdef LD_NAME
-       command = g_strdup_printf ("%s -o %s %s %s.o %s", LD_NAME, tmp_outfile_name, llvm_ofile, acfg->tmpfname, ld_flags);
+       command = g_strdup_printf ("%s -o \"%s\" %s \"%s.o\" %s", LD_NAME, tmp_outfile_name, llvm_ofile, acfg->tmpfname, ld_flags);
 #else
        command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s.o %s", tool_prefix, LD_OPTIONS, tmp_outfile_name, llvm_ofile,
                acfg->tmpfname, ld_flags);
@@ -9187,7 +9245,7 @@ compile_asm (MonoAotCompile *acfg)
        rename (tmp_outfile_name, outfile_name);
 
 #if defined(TARGET_MACH)
-       command = g_strdup_printf ("dsymutil %s", outfile_name);
+       command = g_strdup_printf ("dsymutil \"%s\"", outfile_name);
        aot_printf (acfg, "Executing dsymutil: %s\n", command);
        if (execute_system (command) != 0) {
                return 1;
index 868b4fa6fbb9b77ac259fa5449a9d1f01301e181..ca4f58e074d9eb209c10737ac7a9c815248b7005 100644 (file)
@@ -48,7 +48,6 @@
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/gc-internal.h>
-#include <mono/metadata/monitor.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/mono-endian.h>
 #include <mono/utils/mono-logger-internal.h>
@@ -889,10 +888,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        int atype = decode_value (p, &p);
 
                        ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
-                       if (!ref->method) {
-                               fprintf (stderr, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
-                               exit (1);
-                       }
+                       if (!ref->method)
+                               g_error ("Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
                        break;
                }
                case MONO_WRAPPER_WRITE_BARRIER:
@@ -1834,10 +1831,8 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        }
 
        if (!sofile && !globals) {
-               if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows) {
-                       fprintf (stderr, "Failed to load AOT module '%s' in aot-only mode.\n", aot_name);
-                       exit (1);
-               }
+               if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows)
+                       g_error ("Failed to load AOT module '%s' in aot-only mode.\n", aot_name);
                g_free (aot_name);
                return;
        }
@@ -1864,8 +1859,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
 
        if (!usable) {
                if (mono_aot_only) {
-                       fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode: %s.\n", aot_name, msg);
-                       exit (1);
+                       g_error ("Failed to load AOT module '%s' while running in aot-only mode: %s.\n", aot_name, msg);
                } else {
                        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable: %s.\n", aot_name, msg);
                }
@@ -2078,6 +2072,20 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
 
        init_gots (amodule);
 
+       /*
+        * Register the plt region as a single trampoline so we can unwind from this code
+        */
+       mono_tramp_info_register (
+               mono_tramp_info_create (
+                       NULL,
+                       amodule->plt,
+                       amodule->plt_end - amodule->plt,
+                       NULL,
+                       mono_unwind_get_cie_program ()
+                       ),
+               NULL
+               );
+
        /*
         * Since we store methoddef and classdef tokens when referring to methods/classes in
         * referenced assemblies, we depend on the exact versions of the referenced assemblies.
@@ -2102,10 +2110,8 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
 
        if (amodule->out_of_date) {
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: Module %s is unusable because a dependency is out-of-date.\n", assembly->image->name);
-               if (mono_aot_only) {
-                       fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode because a dependency cannot be found or it is out of date.\n", aot_name);
-                       exit (1);
-               }
+               if (mono_aot_only)
+                       g_error ("Failed to load AOT module '%s' while running in aot-only mode because a dependency cannot be found or it is out of date.\n", aot_name);
        }
        else
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: loaded AOT Module for %s.\n", assembly->image->name);
@@ -2421,10 +2427,8 @@ compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **c
        p += 4;
        table = (gint32*)p;
 
-       if (fde_count > 1) {
-               /* mono_aot_personality () */
-               g_assert (table [0] == -1);
-               *code_start = amodule->methods [table [2]];
+       if (fde_count > 0) {
+               *code_start = amodule->methods [table [0]];
                *code_end = (guint8*)amodule->methods [table [(fde_count - 1) * 2]] + table [fde_count * 2];
        } else {
                *code_start = NULL;
@@ -3359,9 +3363,6 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                ji->data.offset = decode_value (p, &p);
                break;
        case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG:
-       case MONO_PATCH_INFO_MONITOR_ENTER:
-       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
-       case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
        case MONO_PATCH_INFO_GC_NURSERY_START:
        case MONO_PATCH_INFO_JIT_TLS_ID:
@@ -3746,7 +3747,11 @@ find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32
                amodule_unlock (amodule);
                if (!m) {
                        m = decode_resolve_method_ref_with_target (amodule, method, p, &p);
-                       if (m) {
+                       /*
+                        * Can't catche runtime invoke wrappers since it would break
+                        * the check in decode_method_ref_with_target ().
+                        */
+                       if (m && m->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE) {
                                amodule_lock (amodule);
                                g_hash_table_insert (amodule->method_ref_to_method, orig_p, m);
                                amodule_unlock (amodule);
@@ -4549,15 +4554,6 @@ load_function_full (MonoAotModule *amodule, const char *name, MonoTrampInfo **ou
                                        g_assert (res == 1);
                                        target = mono_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL);
                                        target = mono_create_ftnptr_malloc (target);
-                               } else if (!strcmp (ji->data.name, "specific_trampoline_monitor_enter")) {
-                                       target = mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER, mono_get_root_domain (), NULL);
-                                       target = mono_create_ftnptr_malloc (target);
-                               } else if (!strcmp (ji->data.name, "specific_trampoline_monitor_enter_v4")) {
-                                       target = mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER_V4, mono_get_root_domain (), NULL);
-                                       target = mono_create_ftnptr_malloc (target);
-                               } else if (!strcmp (ji->data.name, "specific_trampoline_monitor_exit")) {
-                                       target = mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_EXIT, mono_get_root_domain (), NULL);
-                                       target = mono_create_ftnptr_malloc (target);
                                } else if (!strcmp (ji->data.name, "mono_thread_get_and_clear_pending_exception")) {
                                        target = mono_thread_get_and_clear_pending_exception;
                                } else if (!strcmp (ji->data.name, "debugger_agent_single_step_from_context")) {
@@ -4629,7 +4625,36 @@ mono_aot_get_trampoline_full (const char *name, MonoTrampInfo **out_tinfo)
 gpointer
 mono_aot_get_trampoline (const char *name)
 {
-       return mono_aot_get_trampoline_full (name, NULL);
+       MonoTrampInfo *out_tinfo;
+       gpointer code;
+
+       code =  mono_aot_get_trampoline_full (name, &out_tinfo);
+       mono_tramp_info_register (out_tinfo, NULL);
+
+       return code;
+}
+
+static gpointer
+read_unwind_info (MonoAotModule *amodule, MonoTrampInfo *info, const char *symbol_name)
+{
+       gpointer symbol_addr;
+       guint32 uw_offset, uw_info_len;
+       guint8 *uw_info;
+
+       find_symbol (amodule->sofile, amodule->globals, symbol_name, &symbol_addr);
+
+       if (!symbol_addr)
+               return NULL;
+
+       uw_offset = *(guint32*)symbol_addr;
+       uw_info = amodule->unwind_info + uw_offset;
+       uw_info_len = decode_value (uw_info, &uw_info);
+
+       info->uw_info = uw_info;
+       info->uw_info_len = uw_info_len;
+
+       /* If successful return the address of the following data */
+       return (guint32*)symbol_addr + 1;
 }
 
 #ifdef MONOTOUCH
@@ -4637,6 +4662,25 @@ mono_aot_get_trampoline (const char *name)
 
 static TrampolinePage* trampoline_pages [MONO_AOT_TRAMP_NUM];
 
+static void
+read_page_trampoline_uwinfo (MonoTrampInfo *info, int tramp_type, gboolean is_generic)
+{
+       char symbol_name [128];
+
+       if (tramp_type == MONO_AOT_TRAMP_SPECIFIC)
+               sprintf (symbol_name, "specific_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+       else if (tramp_type == MONO_AOT_TRAMP_STATIC_RGCTX)
+               sprintf (symbol_name, "rgctx_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+       else if (tramp_type == MONO_AOT_TRAMP_IMT_THUNK)
+               sprintf (symbol_name, "imt_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+       else if (tramp_type == MONO_AOT_TRAMP_GSHAREDVT_ARG)
+               sprintf (symbol_name, "gsharedvt_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+       else
+               g_assert_not_reached ();
+
+       read_unwind_info (mono_defaults.corlib->aot_module, info, symbol_name);
+}
+
 static unsigned char*
 get_new_trampoline_from_page (int tramp_type)
 {
@@ -4688,6 +4732,8 @@ get_new_trampoline_from_page (int tramp_type)
        count = 40;
        page = NULL;
        while (page == NULL && count-- > 0) {
+               MonoTrampInfo *gen_info, *sp_info;
+
                addr = 0;
                /* allocate two contiguous pages of memory: the first page will contain the data (like a local constant pool)
                 * while the second will contain the trampolines.
@@ -4728,6 +4774,23 @@ get_new_trampoline_from_page (int tramp_type)
                code = page->trampolines;
                page->trampolines += specific_trampoline_size;
                mono_aot_page_unlock ();
+
+               /* Register the generic part at the beggining of the trampoline page */
+               gen_info = mono_tramp_info_create (NULL, (guint8*)taddr, amodule->info.tramp_page_code_offsets [tramp_type], NULL, NULL);
+               read_page_trampoline_uwinfo (gen_info, tramp_type, TRUE);
+               mono_tramp_info_register (gen_info, NULL);
+               /*
+                * FIXME
+                * Registering each specific trampoline produces a lot of
+                * MonoJitInfo structures. Jump trampolines are also registered
+                * separately.
+                */
+               if (tramp_type != MONO_AOT_TRAMP_SPECIFIC) {
+                       /* Register the rest of the page as a single trampoline */
+                       sp_info = mono_tramp_info_create (NULL, code, page->trampolines_end - code, NULL, NULL);
+                       read_page_trampoline_uwinfo (sp_info, tramp_type, FALSE);
+                       mono_tramp_info_register (sp_info, NULL);
+               }
                return code;
        }
        g_error ("Cannot allocate more trampoline pages: %d", ret);
@@ -4807,6 +4870,7 @@ get_new_gsharedvt_arg_trampoline_from_page (gpointer tramp, gpointer arg)
 }
 
 /* Return a given kind of trampoline */
+/* FIXME set unwind info for these trampolines */
 static gpointer
 get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotModule **out_amodule, guint32 *got_offset, guint32 *out_tramp_size)
 {
@@ -4925,6 +4989,8 @@ mono_aot_get_unbox_trampoline (MonoMethod *method)
        gpointer code;
        guint32 *ut, *ut_end, *entry;
        int low, high, entry_index = 0;
+       gpointer symbol_addr;
+       MonoTrampInfo *tinfo;
 
        if (method->is_inflated && !mono_method_is_generic_sharable_full (method, FALSE, FALSE, FALSE)) {
                method_index = find_aot_method (method, &amodule);
@@ -4964,6 +5030,17 @@ mono_aot_get_unbox_trampoline (MonoMethod *method)
        code = get_call_table_entry (amodule->unbox_trampoline_addresses, entry_index);
        g_assert (code);
 
+       tinfo = mono_tramp_info_create (NULL, code, 0, NULL, NULL);
+
+       symbol_addr = read_unwind_info (amodule, tinfo, "unbox_trampoline_p");
+       if (!symbol_addr) {
+               mono_tramp_info_free (tinfo);
+               return FALSE;
+       }
+
+       tinfo->code_size = *(guint32*)symbol_addr;
+       mono_tramp_info_register (tinfo, NULL);
+
        /* The caller expects an ftnptr */
        return mono_create_ftnptr (mono_domain_get (), code);
 }
index 17e3cfafee9a6476951c576492969fa282691f5b..98bd905faf3550cfae9354d3c34360ba53cdebd9 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.Text;
+using System.Linq;
 using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
@@ -202,6 +203,23 @@ class Tests
                return 0;
        }
 
+       class Foo6 {
+               public T reg_stack_split_inner<T> (int i, int j, T l) {
+                       return l;
+               }
+       }
+
+       [Category("DYNCALL")]
+       static int test_0_arm_dyncall_reg_stack_split () {
+               var m = typeof (Foo6).GetMethod ("reg_stack_split_inner").MakeGenericMethod (new Type[] { typeof (long) });
+               var o = new Foo6 ();
+               if ((long)m.Invoke (o, new object [] { 1, 2, 3 }) != 3)
+                       return 1;
+               if ((long)m.Invoke (o, new object [] { 1, 2, Int64.MaxValue }) != Int64.MaxValue)
+                       return 2;
+               return 0;
+       }
+
        static int test_0_partial_sharing_regress_30204 () {
                var t = typeof (System.Collections.Generic.Comparer<System.Collections.Generic.KeyValuePair<string, string>>);
                var d = new SortedDictionary<string, string> ();
@@ -257,4 +275,20 @@ class Tests
                var c = Comparer<AnEnum>.Default;
                return c.Compare (AnEnum.A, AnEnum.A);
        }
+
+       private static Dictionary<long, TValue> ConvertDictionary<TValue>(Dictionary<long, IList<TValue>> source) {
+               return source.ToDictionary(pair => pair.Key, pair => pair.Value[0]);
+       }
+
+       [Category ("GSHAREDVT")]
+       public static int test_0_gsharedvt_non_variable_arg () {
+               Dictionary<long, IList<int>> data = new Dictionary<long, IList<int>>
+            {
+                               {123L, new List<int> {2}}
+            };
+               Dictionary<long, int> newDict = ConvertDictionary(data);
+               if (newDict.Count != 1)
+                       return 1;
+               return 0;
+       }
 }
index 14488d7b435a2eee3e9f37833904ddea34173ae5..6b5d709f905d335e3fb4b37267dfce4527d97797 100644 (file)
@@ -1238,7 +1238,7 @@ mono_remove_critical_edges (MonoCompile *cfg)
 void
 mono_optimize_branches (MonoCompile *cfg)
 {
-       int i, changed = FALSE;
+       int i, count = 0, changed = FALSE;
        MonoBasicBlock *bb, *bbn;
        guint32 niterations;
        MonoInst *bbn_first_inst;
@@ -1261,6 +1261,11 @@ mono_optimize_branches (MonoCompile *cfg)
 
                /* we skip the entry block (exit is handled specially instead ) */
                for (previous_bb = cfg->bb_entry, bb = cfg->bb_entry->next_bb; bb; previous_bb = bb, bb = bb->next_bb) {
+                       count ++;
+                       if (count == 1000) {
+                               MONO_SUSPEND_CHECK ();
+                               count = 0;
+                       }
                        /* dont touch code inside exception clauses */
                        if (bb->region != -1)
                                continue;
index 194ff2b334534d156594405b3e4c2e26c7bb4f00..49bc57e72e84fd45a78bfde7aac37ac59a1d9e87 100644 (file)
@@ -381,6 +381,7 @@ gc_liveness_def: len:0
 gc_liveness_use: len:0
 gc_spill_slot_liveness_def: len:0
 gc_param_slot_liveness_def: len:0
+gc_safe_point: clob:c src1:i len:40
 
 atomic_add_i4: dest:i src1:i src2:i len:64
 atomic_exchange_i4: dest:i src1:i src2:i len:64
index d9c2a5f2751408528f0551ced8def387fd9aa798..440e6a69e14b46711625758d458e12955ddc9f5a 100644 (file)
@@ -480,3 +480,4 @@ atomic_store_r4: dest:b src1:f len:24
 atomic_store_r8: dest:b src1:f len:20
 
 generic_class_init: src1:a len:44 clob:c
+gc_safe_point: src1:i len:12 clob:c
index ba2ec60d3e727b0a74beeffeeb2126607abed162..e6baf9148fcf1c56f899fdd6592b011d35e16a3d 100644 (file)
@@ -314,5 +314,5 @@ vcall2_membase: src1:b len:16 clob:c
 
 jump_table: dest:i len:8
 
-atomic_add_i4: src1:b src2:i dest:i len:20
+atomic_add_i4: src1:b src2:i dest:i len:28
 atomic_cas_i4: src1:b src2:i src3:i dest:i len:38
index 2bd196cc76c0fd4f1de577e8ae0cc99770a8554f..e9789f9461f375f76c0e242dff149d2dd0d6f68d 100644 (file)
@@ -66,7 +66,7 @@ break: len:1
 call: dest:a clob:c len:17
 tailcall: len:120 clob:c
 br: len:5
-seq_point: len:17
+seq_point: len:24 clob:c
 il_seq_point: len:0
 
 int_beq: len:6
index 5c26451397ead33aa4de0c436978d889780b0e4e..5763be8c8f4ea1066ac29358213047bfd90e1a77 100644 (file)
@@ -225,11 +225,6 @@ typedef struct {
      */
        MonoThreadUnwindState filter_state;
 
-       /*
-        * The callee address of the last mono_runtime_invoke call
-        */
-       gpointer invoke_addr;
-
        gboolean abort_requested;
 
        /*
@@ -273,7 +268,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 40
+#define MINOR_VERSION 41
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -655,12 +650,15 @@ static MonoNativeTlsKey debugger_tls_id;
 static gboolean vm_start_event_sent, vm_death_event_sent, disconnected;
 
 /* Maps MonoInternalThread -> DebuggerTlsData */
+/* Protected by the loader lock */
 static MonoGHashTable *thread_to_tls;
 
 /* Maps tid -> MonoInternalThread */
+/* Protected by the loader lock */
 static MonoGHashTable *tid_to_thread;
 
 /* Maps tid -> MonoThread (not MonoInternalThread) */
+/* Protected by the loader lock */
 static MonoGHashTable *tid_to_thread_obj;
 
 static gsize debugger_thread_id;
@@ -690,7 +688,6 @@ static DebuggerProfiler debugger_profiler;
 
 /* The single step request instance */
 static SingleStepReq *ss_req;
-static gpointer ss_invoke_addr;
 
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
 /* Number of single stepping operations in progress */
@@ -704,6 +701,7 @@ static int major_version, minor_version;
 static gboolean protocol_version_set;
 
 /* A hash table containing all active domains */
+/* Protected by the loader lock */
 static GHashTable *domains;
 
 /* The number of times the runtime is suspended */
@@ -717,9 +715,9 @@ static ReplyPacket reply_packets [128];
 int nreply_packets;
 
 #define dbg_lock() do {        \
-       MONO_TRY_BLOCKING       \
+       MONO_TRY_BLOCKING;                      \
        mono_mutex_lock (&debug_mutex); \
-       MONO_FINISH_TRY_BLOCKING        \
+       MONO_FINISH_TRY_BLOCKING;               \
 } while (0)
 
 #define dbg_unlock() mono_mutex_unlock (&debug_mutex)
@@ -760,10 +758,6 @@ static void emit_assembly_load (gpointer assembly, gpointer user_data);
 
 static void emit_type_load (gpointer key, gpointer type, gpointer user_data);
 
-static void start_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
-static void end_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
 static void jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result);
 
 static void add_pending_breakpoints (MonoMethod *method, MonoJitInfo *jinfo);
@@ -988,7 +982,6 @@ mono_debugger_agent_init (void)
        mono_profiler_install_thread (thread_startup, thread_end);
        mono_profiler_install_assembly (NULL, assembly_load, assembly_unload, NULL);
        mono_profiler_install_jit_end (jit_end);
-       mono_profiler_install_method_invoke (start_runtime_invoke, end_runtime_invoke);
 
        mono_native_tls_alloc (&debugger_tls_id, NULL);
 
@@ -1088,9 +1081,9 @@ finish_agent_init (gboolean on_startup)
                }
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        transport_connect (agent_config.address);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        if (!on_startup) {
                /* Do some which is usually done after sending the VMStart () event */
@@ -1322,9 +1315,9 @@ socket_transport_connect (const char *address)
                        }
                }
 
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                conn_fd = socket_transport_accept (sfd);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
                if (conn_fd == -1)
                        exit (1);
 
@@ -1544,18 +1537,18 @@ transport_handshake (void)
        /* Write handshake message */
        sprintf (handshake_msg, "DWP-Handshake");
        /* Must use try blocking as this can nest into code that runs blocking */
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        do {
                res = transport_send (handshake_msg, strlen (handshake_msg));
        } while (res == -1 && get_last_sock_error () == MONO_EINTR);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        g_assert (res != -1);
 
        /* Read answer */
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        res = transport_recv (buf, strlen (handshake_msg));
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
        if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg)) != 0)) {
                fprintf (stderr, "debugger-agent: DWP handshake failed.\n");
                return FALSE;
@@ -1598,9 +1591,9 @@ stop_debugger_thread (void)
        if (!inited)
                return;
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        transport_close1 ();
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        /* 
         * Wait for the thread to exit.
@@ -1610,18 +1603,18 @@ stop_debugger_thread (void)
         */
        if (GetCurrentThreadId () != debugger_thread_id) {
                do {
-                       MONO_TRY_BLOCKING
+                       MONO_TRY_BLOCKING;
                        mono_mutex_lock (&debugger_thread_exited_mutex);
                        if (!debugger_thread_exited)
                                mono_cond_wait (&debugger_thread_exited_cond, &debugger_thread_exited_mutex);
                        mono_mutex_unlock (&debugger_thread_exited_mutex);
-                       MONO_FINISH_TRY_BLOCKING
+                       MONO_FINISH_TRY_BLOCKING;
                } while (!debugger_thread_exited);
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        transport_close2 ();
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 }
 
 static void
@@ -1815,9 +1808,9 @@ send_packet (int command_set, int command, Buffer *data)
        buffer_add_byte (&buf, command);
        memcpy (buf.buf + 11, data->buf, data->p - data->buf);
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        res = transport_send (buf.buf, len);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        buffer_free (&buf);
 
@@ -1844,9 +1837,9 @@ send_reply_packets (int npackets, ReplyPacket *packets)
                buffer_add_buffer (&buf, packets [i].data);
        }
 
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        res = transport_send (buf.buf, len);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        buffer_free (&buf);
 
@@ -1913,7 +1906,9 @@ typedef struct {
 } ObjRef;
 
 /* Maps objid -> ObjRef */
+/* Protected by the loader lock */
 static GHashTable *objrefs;
+/* Protected by the loader lock */
 static GHashTable *obj_to_objref;
 /* Protected by the dbg lock */
 static MonoGHashTable *suspended_objs;
@@ -2128,8 +2123,10 @@ typedef struct {
 
 typedef struct {
        /* Maps runtime structure -> Id */
+       /* Protected by the dbg lock */
        GHashTable *val_to_id [ID_NUM];
        /* Classes whose class load event has been sent */
+       /* Protected by the loader lock */
        GHashTable *loaded_classes;
        /* Maps MonoClass->GPtrArray of file names */
        GHashTable *source_files;
@@ -2255,24 +2252,19 @@ get_id (MonoDomain *domain, IdType type, gpointer val)
        if (val == NULL)
                return 0;
 
-       mono_loader_lock ();
-
-       mono_domain_lock (domain);
-
        info = get_agent_domain_info (domain);
 
+       dbg_lock ();
+
        if (info->val_to_id [type] == NULL)
                info->val_to_id [type] = g_hash_table_new (mono_aligned_addr_hash, NULL);
 
        id = g_hash_table_lookup (info->val_to_id [type], val);
        if (id) {
-               mono_domain_unlock (domain);
-               mono_loader_unlock ();
+               dbg_unlock ();
                return id->id;
        }
 
-       dbg_lock ();
-
        id = g_new0 (Id, 1);
        /* Reserve id 0 */
        id->id = ids [type]->len + 1;
@@ -2284,10 +2276,6 @@ get_id (MonoDomain *domain, IdType type, gpointer val)
 
        dbg_unlock ();
 
-       mono_domain_unlock (domain);
-
-       mono_loader_unlock ();
-
        return id->id;
 }
 
@@ -2520,7 +2508,7 @@ get_last_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
 {
        GetLastFrameUserData *data = user_data;
 
-       if (info->type == FRAME_TYPE_MANAGED_TO_NATIVE)
+       if (info->type == FRAME_TYPE_MANAGED_TO_NATIVE || info->type == FRAME_TYPE_TRAMPOLINE)
                return FALSE;
 
        if (!data->last_frame_set) {
@@ -2556,7 +2544,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji)
        // FIXME: Races when the thread leaves managed code before hitting a single step
        // event.
 
-       if (ji) {
+       if (ji && !ji->is_trampoline) {
                /* Running managed code, will be suspended by the single step code */
                DEBUG_PRINTF (1, "[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)(gsize)tid, jinfo_get_method (ji)->name, ip);
        } else {
@@ -2648,7 +2636,11 @@ debugger_interrupt_critical (MonoThreadInfo *info, gpointer user_data)
        MonoJitInfo *ji;
 
        data->valid_info = TRUE;
-       ji = mono_jit_info_table_find (mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN], MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
+       ji = mono_jit_info_table_find_internal (
+                       mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN],
+                       MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx),
+                       TRUE,
+                       TRUE);
 
        /* This is signal safe */
        thread_interrupt (data->tls, info, ji);
@@ -2744,9 +2736,9 @@ suspend_vm (void)
 {
        mono_loader_lock ();
 
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (&suspend_mutex);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        suspend_count ++;
 
@@ -2784,9 +2776,9 @@ resume_vm (void)
 
        mono_loader_lock ();
 
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (&suspend_mutex);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        g_assert (suspend_count > 0);
        suspend_count --;
@@ -2830,9 +2822,9 @@ resume_thread (MonoInternalThread *thread)
        tls = mono_g_hash_table_lookup (thread_to_tls, thread);
        g_assert (tls);
        
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (&suspend_mutex);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        g_assert (suspend_count > 0);
 
@@ -2907,9 +2899,9 @@ suspend_current (void)
        tls = mono_native_tls_get_value (debugger_tls_id);
        g_assert (tls);
 
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (&suspend_mutex);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        tls->suspending = FALSE;
        tls->really_suspended = TRUE;
@@ -2921,12 +2913,12 @@ suspend_current (void)
 
        DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ());
 
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        while (suspend_count - tls->resume_count > 0) {
                err = mono_cond_wait (&suspend_cond, &suspend_mutex);
                g_assert (err == 0);
        }
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        tls->suspended = FALSE;
        tls->really_suspended = FALSE;
@@ -3070,7 +3062,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
                        info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset);
        }
 
-       DEBUG_PRINTF (1, "\tFrame: %s:%x(%x) %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed);
+       DEBUG_PRINTF (1, "\tFrame: %s:[il=0x%x, native=0x%x] %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed);
 
        if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
                if (!CHECK_PROTOCOL_VERSION (2, 17))
@@ -3983,60 +3975,6 @@ assembly_unload (MonoProfiler *prof, MonoAssembly *assembly)
        clear_types_for_assembly (assembly);
 }
 
-static void
-start_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
-#if defined(HOST_WIN32) && !defined(__GNUC__)
-       gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
-       gpointer stackptr = __builtin_frame_address (1);
-#endif
-       MonoInternalThread *thread = mono_thread_internal_current ();
-       DebuggerTlsData *tls;
-
-       mono_loader_lock ();
-       
-       tls = mono_g_hash_table_lookup (thread_to_tls, thread);
-       /* Could be the debugger thread with assembly/type load hooks */
-       if (tls)
-               tls->invoke_addr = stackptr;
-
-       mono_loader_unlock ();
-}
-
-static void
-end_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
-       int i;
-#if defined(HOST_WIN32) && !defined(__GNUC__)
-       gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
-       gpointer stackptr = __builtin_frame_address (1);
-#endif
-
-       if (!embedding || ss_req == NULL || stackptr != ss_invoke_addr || ss_req->thread != mono_thread_internal_current ())
-               return;
-
-       /*
-        * We need to stop single stepping when exiting a runtime invoke, since if it is
-        * a step out, it may return to native code, and thus never end.
-        */
-       mono_loader_lock ();
-       ss_invoke_addr = NULL;
-
-       for (i = 0; i < event_requests->len; ++i) {
-               EventRequest *req = g_ptr_array_index (event_requests, i);
-
-               if (req->event_kind == EVENT_KIND_STEP) {
-                       ss_destroy (req->info);
-                       g_ptr_array_remove_index_fast (event_requests, i);
-                       g_free (req);
-                       break;
-               }
-       }
-       mono_loader_unlock ();
-}
-
 static void
 send_type_load (MonoClass *klass)
 {
@@ -4044,18 +3982,17 @@ send_type_load (MonoClass *klass)
        MonoDomain *domain = mono_domain_get ();
        AgentDomainInfo *info = NULL;
 
-       mono_loader_lock ();
-       mono_domain_lock (domain);
-
        info = get_agent_domain_info (domain);
 
+       mono_loader_lock ();
+
        if (!g_hash_table_lookup (info->loaded_classes, klass)) {
                type_load = TRUE;
                g_hash_table_insert (info->loaded_classes, klass, klass);
        }
 
-       mono_domain_unlock (domain);
        mono_loader_unlock ();
+
        if (type_load)
                emit_type_load (klass, klass, NULL);
 }
@@ -4069,13 +4006,12 @@ static void
 send_types_for_domain (MonoDomain *domain, void *user_data)
 {
        AgentDomainInfo *info = NULL;
+
+       info = get_agent_domain_info (domain);
+       g_assert (info);
        
        mono_loader_lock ();
-       mono_domain_lock (domain);
-       info =  get_agent_domain_info (domain);
-       g_assert (info);
        g_hash_table_foreach (info->loaded_classes, emit_type_load, NULL);
-       mono_domain_unlock (domain);
        mono_loader_unlock ();
 }
 
@@ -4148,6 +4084,7 @@ typedef struct {
 } MonoBreakpoint;
 
 /* List of breakpoints */
+/* Protected by the loader lock */
 static GPtrArray *breakpoints;
 /* Maps breakpoint locations to the number of breakpoints at that location */
 static GHashTable *bp_locs;
@@ -4247,7 +4184,7 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
 #endif
        }
 
-       DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:0x%x [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, inst->ip, count);
+       DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:[il=0x%x,native=0x%x] [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, (int)it.seq_point.native_offset, inst->ip, count);
 }
 
 static void
@@ -4274,6 +4211,9 @@ remove_breakpoint (BreakpointInstance *inst)
 #endif
 }      
 
+/*
+ * This doesn't take any locks.
+ */
 static inline gboolean
 bp_matches_method (MonoBreakpoint *bp, MonoMethod *method)
 {
@@ -4341,11 +4281,16 @@ add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji)
                }
 
                if (!found) {
+                       MonoMethod *declaring = NULL;
+
                        jmethod = jinfo_get_method (ji);
+                       if (jmethod->is_inflated)
+                               declaring = mono_method_get_declaring_generic_method (jmethod);
+
                        mono_domain_lock (domain);
                        seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, jmethod);
-                       if (!seq_points && jmethod->is_inflated)
-                               seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, mono_method_get_declaring_generic_method (jmethod));
+                       if (!seq_points && declaring)
+                               seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, declaring);
                        mono_domain_unlock (domain);
                        if (!seq_points)
                                /* Could be AOT code */
@@ -4402,6 +4347,10 @@ set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req, MonoError
        MonoDomain *domain;
        MonoMethod *m;
        MonoSeqPointInfo *seq_points;
+       GPtrArray *methods;
+       GPtrArray *method_domains;
+       GPtrArray *method_seq_points;
+       int i;
 
        if (error)
                mono_error_init (error);
@@ -4420,27 +4369,40 @@ set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req, MonoError
 
        DEBUG_PRINTF (1, "[dbg] Setting %sbreakpoint at %s:0x%x.\n", (req->event_kind == EVENT_KIND_STEP) ? "single step " : "", method ? mono_method_full_name (method, TRUE) : "<all>", (int)il_offset);
 
-       mono_loader_lock ();
+       methods = g_ptr_array_new ();
+       method_domains = g_ptr_array_new ();
+       method_seq_points = g_ptr_array_new ();
 
+       mono_loader_lock ();
        g_hash_table_iter_init (&iter, domains);
        while (g_hash_table_iter_next (&iter, (void**)&domain, NULL)) {
                mono_domain_lock (domain);
-
                g_hash_table_iter_init (&iter2, domain_jit_info (domain)->seq_points);
                while (g_hash_table_iter_next (&iter2, (void**)&m, (void**)&seq_points)) {
-                       if (bp_matches_method (bp, m))
-                               set_bp_in_method (domain, m, seq_points, bp, error);
+                       if (bp_matches_method (bp, m)) {
+                               /* Save the info locally to simplify the code inside the domain lock */
+                               g_ptr_array_add (methods, m);
+                               g_ptr_array_add (method_domains, domain);
+                               g_ptr_array_add (method_seq_points, seq_points);
+                       }
                }
-
                mono_domain_unlock (domain);
        }
 
-       mono_loader_unlock ();
+       for (i = 0; i < methods->len; ++i) {
+               m = g_ptr_array_index (methods, i);
+               domain = g_ptr_array_index (method_domains, i);
+               seq_points = g_ptr_array_index (method_seq_points, i);
+               set_bp_in_method (domain, m, seq_points, bp, error);
+       }
 
-       mono_loader_lock ();
        g_ptr_array_add (breakpoints, bp);
        mono_loader_unlock ();
 
+       g_ptr_array_free (methods, TRUE);
+       g_ptr_array_free (method_domains, TRUE);
+       g_ptr_array_free (method_seq_points, TRUE);
+
        if (error && !mono_error_ok (error)) {
                clear_breakpoint (bp);
                return NULL;
@@ -4637,7 +4599,7 @@ process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal)
 
        ip = MONO_CONTEXT_GET_IP (ctx);
        ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, NULL);
-       g_assert (ji);
+       g_assert (ji && !ji->is_trampoline);
        method = jinfo_get_method (ji);
 
        /* Compute the native offset of the breakpoint from the ip */
@@ -4669,7 +4631,7 @@ process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal)
 
        g_assert (found_sp);
 
-       DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x, sp il offset=0x%x.\n", (gpointer)GetCurrentThreadId (), method->name, ip, native_offset, sp.il_offset);
+       DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, [il=0x%x,native=0x%x].\n", (gpointer)GetCurrentThreadId (), method->name, ip, sp.il_offset, native_offset);
 
        bp = NULL;
        for (i = 0; i < breakpoints->len; ++i) {
@@ -4901,7 +4863,7 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
        }
 
        ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain);
-       g_assert (ji);
+       g_assert (ji && !ji->is_trampoline);
        method = jinfo_get_method (ji);
        g_assert (method);
 
@@ -5054,17 +5016,6 @@ start_single_stepping (void)
 
        if (val == 1)
                mono_arch_start_single_stepping ();
-
-       if (ss_req != NULL && ss_invoke_addr == NULL) {
-               DebuggerTlsData *tls;
-       
-               mono_loader_lock ();
-       
-               tls = mono_g_hash_table_lookup (thread_to_tls, ss_req->thread);
-               ss_invoke_addr = tls->invoke_addr;
-               
-               mono_loader_unlock ();
-       }
 #else
        g_assert_not_reached ();
 #endif
@@ -5078,8 +5029,6 @@ stop_single_stepping (void)
 
        if (val == 0)
                mono_arch_stop_single_stepping ();
-       if (ss_req != NULL)
-               ss_invoke_addr = NULL;
 #else
        g_assert_not_reached ();
 #endif
@@ -6478,8 +6427,9 @@ clear_types_for_assembly (MonoAssembly *assembly)
                /* Can happen during shutdown */
                return;
 
-       mono_loader_lock ();
        info = get_agent_domain_info (domain);
+
+       mono_loader_lock ();
        g_hash_table_foreach_remove (info->loaded_classes, type_comes_from_assembly, assembly);
        mono_loader_unlock ();
 }
@@ -7063,7 +7013,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                 * Store the invoke data into tls, the thread will execute it after it is
                 * resumed.
                 */
-               if (tls->pending_invoke)
+               if (tls->pending_invoke || tls->invoke)
                        return ERR_NOT_SUSPENDED;
                tls->pending_invoke = g_new0 (InvokeData, 1);
                tls->pending_invoke->id = id;
@@ -9171,6 +9121,7 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
        char *s;
        int i, index, length;
        gunichar2 *c;
+       gboolean use_utf16 = FALSE;
 
        objid = decode_objid (p, &p, end);
        err = get_object (objid, (MonoObject**)&str);
@@ -9179,9 +9130,20 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
        switch (command) {
        case CMD_STRING_REF_GET_VALUE:
-               s = mono_string_to_utf8 (str);
-               buffer_add_string (buf, s);
-               g_free (s);
+               if (CHECK_PROTOCOL_VERSION (2, 41)) {
+                       for (i = 0; i < mono_string_length (str); ++i)
+                               if (mono_string_chars (str)[i] == 0)
+                                       use_utf16 = TRUE;
+                       buffer_add_byte (buf, use_utf16 ? 1 : 0);
+               }
+               if (use_utf16) {
+                       buffer_add_int (buf, mono_string_length (str) * 2);
+                       buffer_add_data (buf, (guint8*)mono_string_chars (str), mono_string_length (str) * 2);
+               } else {
+                       s = mono_string_to_utf8 (str);
+                       buffer_add_string (buf, s);
+                       g_free (s);
+               }
                break;
        case CMD_STRING_REF_GET_LENGTH:
                buffer_add_long (buf, mono_string_length (str));
@@ -9579,9 +9541,9 @@ wait_for_attach (void)
        }
 
        /* Block and wait for client connection */
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
        conn_fd = socket_transport_accept (listen_fd);
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
 
        DEBUG_PRINTF (1, "Accepted connection on %d\n", conn_fd);
        if (conn_fd == -1) {
@@ -9640,9 +9602,9 @@ debugger_thread (void *arg)
        }
        
        while (!attach_failed) {
-               MONO_PREPARE_BLOCKING
+               MONO_PREPARE_BLOCKING;
                res = transport_recv (header, HEADER_LENGTH);
-               MONO_FINISH_BLOCKING
+               MONO_FINISH_BLOCKING;
 
                /* This will break if the socket is closed during shutdown too */
                if (res != HEADER_LENGTH) {
@@ -9677,9 +9639,9 @@ debugger_thread (void *arg)
                data = g_malloc (len - HEADER_LENGTH);
                if (len - HEADER_LENGTH > 0)
                {
-                       MONO_PREPARE_BLOCKING
+                       MONO_PREPARE_BLOCKING;
                        res = transport_recv (data, len - HEADER_LENGTH);
-                       MONO_FINISH_BLOCKING
+                       MONO_FINISH_BLOCKING;
                        if (res != len - HEADER_LENGTH) {
                                DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH);
                                break;
@@ -9769,12 +9731,12 @@ debugger_thread (void *arg)
 
        mono_set_is_debugger_attached (FALSE);
        
-       MONO_TRY_BLOCKING
+       MONO_TRY_BLOCKING;
        mono_mutex_lock (&debugger_thread_exited_mutex);
        debugger_thread_exited = TRUE;
        mono_cond_signal (&debugger_thread_exited_cond);
        mono_mutex_unlock (&debugger_thread_exited_mutex);
-       MONO_FINISH_TRY_BLOCKING
+       MONO_FINISH_TRY_BLOCKING;
 
        DEBUG_PRINTF (1, "[dbg] Debugger thread exited.\n");
        
index decdd5ec10e092bf8f0eccbdf31d72b5174171d7..fcbbe5bdc2636bfdda0036e1bc2d193f248acdf6 100644 (file)
@@ -407,7 +407,7 @@ emit_fde (MonoDwarfWriter *w, int fde_index, char *start_symbol, char *end_symbo
        }
 
        /* Convert the list of MonoUnwindOps to the format used by DWARF */     
-       uw_info = mono_unwind_ops_encode (l, &uw_info_len);
+       uw_info = mono_unwind_ops_encode_full (l, &uw_info_len, FALSE);
        emit_bytes (w, uw_info, uw_info_len);
        g_free (uw_info);
 
index 1a34f6e2f5234cc335c40a7558e315ce8dabb897..4f7e336e6d2ee53f4ef524810ac7d667809d8723 100644 (file)
@@ -540,7 +540,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint8 *unwind_info;
                guint8 *epilog = NULL;
 
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
 
@@ -882,7 +885,7 @@ mono_arch_exceptions_init (void)
                        MonoTrampInfo *info = l->data;
 
                        mono_register_jit_icall (info->code, g_strdup (info->name), NULL, TRUE);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
                }
                g_slist_free (tramps);
        }
index e06e2cb656e99098adb626242839da2136de113b..b478a713bc5e108ea30e7d59ed5e4a2f8c24a9c0 100644 (file)
@@ -376,7 +376,7 @@ mono_arch_exceptions_init (void)
                        MonoTrampInfo *info = l->data;
 
                        mono_register_jit_icall (info->code, g_strdup (info->name), NULL, TRUE);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
                }
                g_slist_free (tramps);
        }
@@ -408,7 +408,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint32 unwind_info_len;
                guint8 *unwind_info;
 
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
 
index 83ff89b174ed2360e8dbbe825f2e98e4e75a072c..b9299cbe4fd3181883a5bf90efa29e896e4f6328 100644 (file)
@@ -545,7 +545,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
        }
 
        if (ji) {
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
                frame->ji = ji;
 
                //print_ctx (new_ctx);
index dcdb320e29fab388f395547133e11ccc5a0efff3..f8d9dedff2ce60e3e223f4189b57c5452a456c4d 100644 (file)
@@ -410,7 +410,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint32 unwind_info_len;
                guint8 *unwind_info;
 
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
 
index 922a1c6870bff045cb89dd12c9d612617f1153d2..1088e12ea426ae53272624cb11c3a49de19e8863 100644 (file)
@@ -532,13 +532,16 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint32 unwind_info_len;
                guint8 *unwind_info;
 
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
 
                sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_SP (ctx);
                MONO_CONTEXT_SET_BP (new_ctx, sframe->sp);
-               if (jinfo_get_method (ji)->save_lmf) {
+               if (!ji->is_trampoline && jinfo_get_method (ji)->save_lmf) {
                        /* sframe->sp points just past the end of the LMF */
                        guint8 *lmf_addr = (guint8*)sframe->sp - sizeof (MonoLMF);
                        memcpy (&new_ctx->fregs, lmf_addr + G_STRUCT_OFFSET (MonoLMF, fregs), sizeof (double) * MONO_SAVED_FREGS);
@@ -653,7 +656,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s
                const char *method;
                /* we don't do much now, but we can warn the user with a useful message */
                fprintf (stderr, "Stack overflow: IP: %p, SP: %p\n", mono_arch_ip_from_context (sigctx), (gpointer)UCONTEXT_REG_Rn(uc, 1));
-               if (ji && jinfo_get_method (ji))
+               if (ji && !ji->is_trampoline && jinfo_get_method (ji))
                        method = mono_method_full_name (jinfo_get_method (ji), TRUE);
                else
                        method = "Unmanaged";
@@ -783,3 +786,16 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        return result;
 #endif
 }
+
+
+// FIX ME: This is not complete
+void
+mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data)
+{
+       uintptr_t sp = (uintptr_t) MONO_CONTEXT_GET_SP(ctx);
+       sp -= PPC_MINIMAL_STACK_SIZE;
+       *(unsigned long *)sp = MONO_CONTEXT_GET_SP(ctx);
+       MONO_CONTEXT_SET_BP(ctx, sp);
+       MONO_CONTEXT_SET_IP(ctx, (unsigned long) async_cb);
+}
+
index c3714f94ee0d37bc67485bd437ffd9e65ca95e32..83d5f6b1368771d1509397f61ba852a7f51541d7 100644 (file)
@@ -478,7 +478,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint8 *unwind_info;
                mgreg_t regs[16];
 
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
 
index a5b197c8c4f5ccfd559410fbd546bf8d8bc5c9de..b3b5633597644d39ff345274d0fc4f2749b21d66 100644 (file)
@@ -350,7 +350,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
        *new_ctx = *ctx;
 
        if (ji != NULL) {
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                /* Restore ip and sp from the saved register window */
                window = MONO_SPARC_WINDOW_ADDR (ctx->sp);
index 3b4b21c1dffd861d6bb9870786fa18283645983a..3db25ca7f810f8ab363fe926b3a75c355c3e10da 100644 (file)
@@ -564,8 +564,7 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea
         * <return addr> <- esp (unaligned on apple)
         */
 
-       mono_add_unwind_op_def_cfa (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_ESP, 4);
-       mono_add_unwind_op_offset (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_NREG, -4);
+       unwind_ops = mono_arch_get_cie_program ();
 
        /* Alloc frame */
        x86_alu_reg_imm (code, X86_SUB, X86_ESP, stack_size);
@@ -717,6 +716,7 @@ void
 mono_arch_exceptions_init (void)
 {
        guint8 *tramp;
+       MonoTrampInfo *tinfo;
 
 /* 
  * If we're running WoW64, we need to set the usermode exception policy 
@@ -745,22 +745,28 @@ mono_arch_exceptions_init (void)
        }
 
        /* LLVM needs different throw trampolines */
-       tramp = get_throw_trampoline ("llvm_throw_exception_trampoline", FALSE, TRUE, FALSE, FALSE, FALSE, NULL, FALSE);
+       tramp = get_throw_trampoline ("llvm_throw_exception_trampoline", FALSE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE);
        mono_register_jit_icall (tramp, "llvm_throw_exception_trampoline", NULL, TRUE);
+       mono_tramp_info_register (tinfo, NULL);
 
-       tramp = get_throw_trampoline ("llvm_rethrow_exception_trampoline", TRUE, TRUE, FALSE, FALSE, FALSE, NULL, FALSE);
+       tramp = get_throw_trampoline ("llvm_rethrow_exception_trampoline", TRUE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE);
        mono_register_jit_icall (tramp, "llvm_rethrow_exception_trampoline", NULL, TRUE);
+       mono_tramp_info_register (tinfo, NULL);
 
-       tramp = get_throw_trampoline ("llvm_throw_corlib_exception_trampoline", FALSE, TRUE, TRUE, FALSE, FALSE, NULL, FALSE);
+       tramp = get_throw_trampoline ("llvm_throw_corlib_exception_trampoline", FALSE, TRUE, TRUE, FALSE, FALSE, &tinfo, FALSE);
        mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_trampoline", NULL, TRUE);
+       mono_tramp_info_register (tinfo, NULL);
 
-       tramp = get_throw_trampoline ("llvm_throw_corlib_exception_abs_trampoline", FALSE, TRUE, TRUE, TRUE, FALSE, NULL, FALSE);
+       tramp = get_throw_trampoline ("llvm_throw_corlib_exception_abs_trampoline", FALSE, TRUE, TRUE, TRUE, FALSE, &tinfo, FALSE);
        mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_abs_trampoline", NULL, TRUE);
+       mono_tramp_info_register (tinfo, NULL);
 
-       tramp = get_throw_trampoline ("llvm_resume_unwind_trampoline", FALSE, FALSE, FALSE, FALSE, TRUE, NULL, FALSE);
+       tramp = get_throw_trampoline ("llvm_resume_unwind_trampoline", FALSE, FALSE, FALSE, FALSE, TRUE, &tinfo, FALSE);
        mono_register_jit_icall (tramp, "llvm_resume_unwind_trampoline", NULL, TRUE);
+       mono_tramp_info_register (tinfo, NULL);
 
-       signal_exception_trampoline = mono_x86_get_signal_exception_trampoline (NULL, FALSE);
+       signal_exception_trampoline = mono_x86_get_signal_exception_trampoline (&tinfo, FALSE);
+       mono_tramp_info_register (tinfo, NULL);
 }
 
 /*
@@ -788,7 +794,10 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint32 unwind_info_len;
                guint8 *unwind_info;
 
-               frame->type = FRAME_TYPE_MANAGED;
+               if (ji->is_trampoline)
+                       frame->type = FRAME_TYPE_TRAMPOLINE;
+               else
+                       frame->type = FRAME_TYPE_MANAGED;
 
                unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
 
@@ -931,11 +940,12 @@ mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot)
 
        start = code = mono_global_codeman_reserve (128);
 
+       /* FIXME no unwind before we push ip */
        /* Caller ip */
        x86_push_reg (code, X86_ECX);
 
-       mono_add_unwind_op_def_cfa (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_ESP, 4);
-       mono_add_unwind_op_offset (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_NREG, -4);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, start, X86_ESP, 4);
+       mono_add_unwind_op_offset (unwind_ops, code, start, X86_NREG, -4);
 
        /* Fix the alignment to be what apple expects */
        stack_size = 12;
index 2f60cb70210c758dfbc8e718b972814a4115ed3e..f5ee9bbbf6069effddeddeeed2067809a3058226 100644 (file)
@@ -1300,6 +1300,7 @@ public class Tests
 
        interface IFaceBox {
                object box<T> (T t);
+               bool is_null<T> (T t);
        }
 
        class ClassBox : IFaceBox {
@@ -1307,6 +1308,12 @@ public class Tests
                        object o = t;
                        return o;
                }
+
+               public bool is_null<T> (T t) {
+                       if (!(default(T) == null))
+                               return false;
+                       return true;
+               }
        }
 
        public static int test_0_nullable_box () {
@@ -1329,6 +1336,15 @@ public class Tests
                return 0;
        }
 
+       public static int test_0_nullable_box_brtrue_opt () {
+               IFaceBox c = new ClassBox ();
+
+               if (c.is_null<double?> (null))
+                       return 0;
+               else
+                       return 1;
+       }
+
        interface IFaceUnbox2 {
                T unbox<T> (object o);
        }
index eb118be0c9bf72d7da46ae02be41daf88a70fe20..b1c38b700076b9186e73838f4a6d20b08b768894 100644 (file)
@@ -54,7 +54,6 @@
 #include <mono/metadata/security-manager.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/security-core-clr.h>
-#include <mono/metadata/monitor.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/profiler.h>
 #include <mono/metadata/debug-mono-symfile.h>
@@ -149,9 +148,6 @@ static int inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSigna
 /* helper methods signatures */
 static MonoMethodSignature *helper_sig_domain_get;
 static MonoMethodSignature *helper_sig_rgctx_lazy_fetch_trampoline;
-static MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline;
-static MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline_llvm;
-static MonoMethodSignature *helper_sig_monitor_enter_v4_trampoline_llvm;
 
 /*
  * Instruction metadata
@@ -356,9 +352,6 @@ mono_create_helper_signatures (void)
 {
        helper_sig_domain_get = mono_create_icall_signature ("ptr");
        helper_sig_rgctx_lazy_fetch_trampoline = mono_create_icall_signature ("ptr ptr");
-       helper_sig_monitor_enter_exit_trampoline = mono_create_icall_signature ("void");
-       helper_sig_monitor_enter_exit_trampoline_llvm = mono_create_icall_signature ("void object");
-       helper_sig_monitor_enter_v4_trampoline_llvm = mono_create_icall_signature ("void object ptr");
 }
 
 static MONO_NEVER_INLINE void
@@ -4318,6 +4311,7 @@ icall_is_direct_callable (MonoCompile *cfg, MonoMethod *cmethod)
                g_hash_table_insert (h, (char*)"Decimal", GUINT_TO_POINTER (1));
                g_hash_table_insert (h, (char*)"Number", GUINT_TO_POINTER (1));
                g_hash_table_insert (h, (char*)"Buffer", GUINT_TO_POINTER (1));
+               g_hash_table_insert (h, (char*)"Monitor", GUINT_TO_POINTER (1));
                mono_memory_barrier ();
                direct_icall_type_hash = h;
        }
@@ -6022,59 +6016,6 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                                return ins;
                        }
                }
-       } else if (cmethod->klass == mono_defaults.monitor_class) {
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG)
-               if (strcmp (cmethod->name, "Enter") == 0 && fsig->param_count == 1) {
-                       MonoCallInst *call;
-
-                       if (COMPILE_LLVM (cfg)) {
-                               /* 
-                                * Pass the argument normally, the LLVM backend will handle the
-                                * calling convention problems.
-                                */
-                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER, NULL, helper_sig_monitor_enter_exit_trampoline_llvm, args);
-                       } else {
-                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER,
-                                           NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
-                               mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
-                                                                                          MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
-                       }
-
-                       return (MonoInst*)call;
-#if defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
-               } else if (strcmp (cmethod->name, "Enter") == 0 && fsig->param_count == 2) {
-                       MonoCallInst *call;
-
-                       if (COMPILE_LLVM (cfg)) {
-                               /*
-                                * Pass the argument normally, the LLVM backend will handle the
-                                * calling convention problems.
-                                */
-                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER_V4, NULL, helper_sig_monitor_enter_v4_trampoline_llvm, args);
-                       } else {
-                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER_V4,
-                                           NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
-                               mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg, MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
-                               mono_call_inst_add_outarg_reg (cfg, call, args [1]->dreg, MONO_ARCH_MONITOR_LOCK_TAKEN_REG, FALSE);
-                       }
-
-                       return (MonoInst*)call;
-#endif
-               } else if (strcmp (cmethod->name, "Exit") == 0 && fsig->param_count == 1) {
-                       MonoCallInst *call;
-
-                       if (COMPILE_LLVM (cfg)) {
-                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT, NULL, helper_sig_monitor_enter_exit_trampoline_llvm, args);
-                       } else {
-                               call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT,
-                                           NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
-                               mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
-                                                                                          MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
-                       }
-
-                       return (MonoInst*)call;
-               }
-#endif
        } else if (cmethod->klass->image == mono_defaults.corlib &&
                           (strcmp (cmethod->klass->name_space, "System.Threading") == 0) &&
                           (strcmp (cmethod->klass->name, "Interlocked") == 0)) {
@@ -6975,7 +6916,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
        cfg->disable_inline = prev_disable_inline;
        cfg->inline_depth --;
 
-       if ((costs >= 0 && costs < 60) || inline_always) {
+       if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))) {
                if (cfg->verbose_level > 2)
                        printf ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
                
@@ -7918,8 +7859,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                MONO_INST_NEW (cfg, ins, OP_START_HANDLER);
                                MONO_ADD_INS (tblock, ins);
 
-                               if (seq_points && clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY) {
+                               if (seq_points && clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_FILTER) {
                                        /* finally clauses already have a seq point */
+                                       /* seq points for filter clauses are emitted below */
                                        NEW_SEQ_POINT (cfg, ins, clause->handler_offset, TRUE);
                                        MONO_ADD_INS (tblock, ins);
                                }
@@ -7961,6 +7903,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                 */
                                EMIT_NEW_DUMMY_USE (cfg, dummy_use, tblock->in_stack [0]);
 #endif
+
+                               if (seq_points && clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
+                                       NEW_SEQ_POINT (cfg, ins, clause->handler_offset, TRUE);
+                                       MONO_ADD_INS (tblock, ins);
+                               }
                                
                                if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
                                        GET_BBLOCK (cfg, tblock, ip + clause->data.filter_offset);
@@ -8848,6 +8795,20 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                CHECK_CFG_ERROR;
                        }
 
+                       /* See code below */
+                       if (cmethod->klass == mono_defaults.monitor_class && !strcmp (cmethod->name, "Enter") && mono_method_signature (cmethod)->param_count == 1) {
+                               MonoBasicBlock *tbb;
+
+                               GET_BBLOCK (cfg, tbb, ip + 5);
+                               if (tbb->try_start && MONO_REGION_FLAGS(tbb->region) == MONO_EXCEPTION_CLAUSE_FINALLY) {
+                                       /*
+                                        * We want to extend the try block to cover the call, but we can't do it if the
+                                        * call is made directly since its followed by an exception check.
+                                        */
+                                       direct_icall = FALSE;
+                               }
+                       }
+
                        mono_save_token_info (cfg, image, token, cil_method);
 
                        if (!(seq_point_locs && mono_bitset_test_fast (seq_point_locs, ip + 5 - header->code)))
@@ -10673,6 +10634,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                        // FIXME: LLVM can't handle the inconsistent bb linking
                        if (!mono_class_is_nullable (klass) &&
+                               !mini_is_gsharedvt_klass (klass) &&
                                ip + 5 < end && ip_in_bb (cfg, cfg->cbb, ip + 5) &&
                                (ip [5] == CEE_BRTRUE || 
                                 ip [5] == CEE_BRTRUE_S ||
@@ -10843,11 +10805,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                ensure_method_is_allowed_to_access_field (cfg, method, field);
                        */
 
+                       ftype = mono_field_get_type (field);
+
                        /*
                         * LDFLD etc. is usable on static fields as well, so convert those cases to
                         * the static case.
                         */
-                       if (is_instance && field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+                       if (is_instance && ftype->attrs & FIELD_ATTRIBUTE_STATIC) {
                                switch (op) {
                                case CEE_LDFLD:
                                        op = CEE_LDSFLD;
@@ -11032,8 +10996,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        /* STATIC CASE */
                        context_used = mini_class_check_context_used (cfg, klass);
 
-                       ftype = mono_field_get_type (field);
-
                        if (ftype->attrs & FIELD_ATTRIBUTE_LITERAL)
                                UNVERIFIED;
 
index 3f966b3a1989b3afc838c6ebacfae70db10a03ea..f0ca62d8d97a358f1e46b44e832fc73b5abcffb9 100644 (file)
@@ -65,9 +65,6 @@ static gboolean optimize_for_xen = TRUE;
 #define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
 static mono_mutex_t mini_arch_mutex;
 
-MonoBreakpointInfo
-mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
 /*
  * The code generated for sequence points reads from this location, which is
  * made read-only when single stepping is enabled.
@@ -7815,11 +7812,14 @@ mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code)
 #define MAX_ARCH_DELEGATE_PARAMS 10
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count)
 {
        guint8 *code, *start;
+       GSList *unwind_ops = NULL;
        int i;
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        if (has_target) {
                start = code = mono_global_codeman_reserve (64);
 
@@ -7856,8 +7856,13 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
        nacl_global_codeman_validate (&start, 64, &code);
        mono_arch_flush_icache (start, code - start);
 
-       if (code_len)
-               *code_len = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+               g_free (name);
+       }
 
        if (mono_jit_map_is_enabled ()) {
                char *buff;
@@ -7877,16 +7882,20 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
 #define MAX_VIRTUAL_DELEGATE_OFFSET 32
 
 static gpointer
-get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *code_len)
+get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, int offset)
 {
        guint8 *code, *start;
        int size = 20;
+       char *tramp_name;
+       GSList *unwind_ops;
 
-       if (offset / sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
+       if (offset / (int)sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
                return NULL;
 
        start = code = mono_global_codeman_reserve (size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        /* Replace the this argument with the target */
        amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
        amd64_mov_reg_membase (code, AMD64_ARG_REG1, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 8);
@@ -7901,8 +7910,12 @@ get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *co
        amd64_jump_membase (code, AMD64_RAX, offset);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
 
-       if (code_len)
-               *code_len = code - start;
+       if (load_imt_reg)
+               tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
+       else
+               tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+       *info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
+       g_free (tramp_name);
 
        return start;
 }
@@ -7917,31 +7930,23 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0);
+       res = g_slist_prepend (res, info);
 
-       for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+               get_delegate_invoke_impl (&info, FALSE, i);
+               res = g_slist_prepend (res, info);
        }
 
-       for (i = 0; i < MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
-               code = get_delegate_virtual_invoke_impl (TRUE, i * SIZEOF_VOID_P, &code_len);
-               tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+               get_delegate_virtual_invoke_impl (&info, TRUE, - i * SIZEOF_VOID_P);
+               res = g_slist_prepend (res, info);
 
-               code = get_delegate_virtual_invoke_impl (FALSE, i * SIZEOF_VOID_P, &code_len);
-               tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+               get_delegate_virtual_invoke_impl (&info, FALSE, i * SIZEOF_VOID_P);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -7966,10 +7971,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                if (cached)
                        return cached;
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL);
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0);
+                       mono_tramp_info_register (info, NULL);
+               }
 
                mono_memory_barrier ();
 
@@ -7991,7 +7999,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+                       mono_tramp_info_register (info, NULL);
                }
 
                mono_memory_barrier ();
@@ -8005,7 +8015,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 gpointer
 mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
 {
-       return get_delegate_virtual_invoke_impl (load_imt_reg, offset, NULL);
+       MonoTrampInfo *info;
+       gpointer code;
+
+       code = get_delegate_virtual_invoke_impl (&info, load_imt_reg, offset);
+       if (code)
+               mono_tramp_info_register (info, NULL);
+       return code;
 }
 
 void
@@ -8064,6 +8080,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        int size = 0;
        guint8 *code, *start;
        gboolean vtable_is_32bit = ((gsize)(vtable) == (gsize)(int)(gsize)(vtable));
+       GSList *unwind_ops;
 
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
@@ -8126,6 +8143,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                code = mono_domain_code_reserve (domain, size);
 #endif
        start = code;
+
+       unwind_ops = mono_arch_get_cie_program ();
+
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
                item->code_target = code;
@@ -8216,6 +8236,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        nacl_domain_code_validate(domain, &start, size, &code);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
index 6f70402b8c8decddcebe0217b765ccfccd6d4683..c494c69fbbcaf677a3570478b9d2d60dfe5e0880 100644 (file)
@@ -325,8 +325,6 @@ typedef struct {
 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
 #define MONO_ARCH_HAVE_LIVERANGE_OPS 1
 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
-#define MONO_ARCH_MONITOR_OBJECT_REG MONO_AMD64_ARG_REG1
-#define MONO_ARCH_MONITOR_LOCK_TAKEN_REG MONO_AMD64_ARG_REG2
 #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
 
 #define MONO_ARCH_AOT_SUPPORTED 1
@@ -406,13 +404,6 @@ mono_amd64_get_exception_trampolines (gboolean aot);
 int
 mono_amd64_get_tls_gs_offset (void) MONO_LLVM_INTERNAL;
 
-typedef struct {
-       guint8 *address;
-       guint8 saved_byte;
-} MonoBreakpointInfo;
-
-extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
 #ifdef TARGET_WIN32
 
 void mono_arch_unwindinfo_add_push_nonvol (gpointer* monoui, gpointer codebegin, gpointer nextip, guchar reg );
index f4e8db7feec28a3e4fe0cb2f4286f6651082d5fe..1f7204a884b0d09aae0f4319b5fc8721ab2d1b98 100644 (file)
         * within can be tracked. The tls value is returned in R0.
         */
 
+.macro DECLARE_GLOBAL_SYMBOL name
+#ifdef TARGET_MACH
+       .global _\name
+_\name:
+#else
+       .global \name
+\name:
+#endif
+.endm
+
        .text
 /* no .arch on clang. it only supports armv6+ anyway */
 #ifndef TARGET_MACH
 #endif
        .arm
        .align 4
-#ifdef TARGET_MACH
-       .global _mono_fast_get_tls_key
-_mono_fast_get_tls_key :
-#else
-       .global mono_fast_get_tls_key
-mono_fast_get_tls_key :
-#endif
+
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key
 #if defined(__linux__)
        mrc     p15, 0, r1, c13, c0, 3
 #if defined(HAVE_KW_THREAD)
@@ -42,6 +47,7 @@ mono_fast_get_tls_key :
        ldr     r0, [r1, r0, lsl #2]
        bx      lr
 #endif
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key_end
 
        /*
         * The following thunks fetch the value corresponding to the key/offset
@@ -50,13 +56,7 @@ mono_fast_get_tls_key :
         */
 
        .align 4
-#ifdef TARGET_MACH
-       .global _mono_fallback_get_tls_key
-_mono_fallback_get_tls_key :
-#else
-       .global mono_fallback_get_tls_key
-mono_fallback_get_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fallback_get_tls_key
 #if defined(__linux__)
        mov     r1, r0
        mvn     r0, #0xf000
@@ -82,13 +82,7 @@ mono_fallback_get_tls_key :
         */
 
        .align 4
-#ifdef TARGET_MACH
-       .global _mono_fast_set_tls_key
-_mono_fast_set_tls_key :
-#else
-       .global mono_fast_set_tls_key
-mono_fast_set_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key
 #if defined(__linux__)
        mrc     p15, 0, r2, c13, c0, 3
 #if defined(HAVE_KW_THREAD)
@@ -103,6 +97,7 @@ mono_fast_set_tls_key :
        str     r1, [r2, r0, lsl #2]
        bx      lr
 #endif
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key_end
 
        /*
         * The following thunks set the value corresponding to the key/offset
@@ -111,13 +106,7 @@ mono_fast_set_tls_key :
         */
 
        .align 4
-#ifdef TARGET_MACH
-       .global _mono_fallback_set_tls_key
-_mono_fallback_set_tls_key :
-#else
-       .global mono_fallback_set_tls_key
-mono_fallback_set_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
 #if defined(__linux__)
        mov     r2, r0
        mvn     r0, #0xf000
index e0aa41bc630c56d2bab32d388804f309afd60ec7..30b2494dfc70c21ad396339e5e8cec5f8c86af6f 100644 (file)
@@ -11,4 +11,9 @@ void mono_fast_set_tls_key (int, int);
 int mono_fallback_get_tls_key (int);
 void mono_fallback_set_tls_key (int, int);
 
+/* End of thunks */
+
+void mono_fast_get_tls_key_end (void);
+void mono_fast_set_tls_key_end (void);
+
 #endif
index bf0ecc6eebcf42e6eb85e3eacccb9940eef0b54d..e92a280219623d591227daf9742c2b3c1ae58e0d 100644 (file)
@@ -746,9 +746,10 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit
 #define MAX_ARCH_DELEGATE_PARAMS 3
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count)
 {
        guint8 *code, *start;
+       GSList *unwind_ops = mono_arch_get_cie_program ();
 
        if (has_target) {
                start = code = mono_global_codeman_reserve (12);
@@ -779,9 +780,15 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
                mono_arch_flush_icache (start, size);
        }
 
+       if (has_target) {
+                *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+       } else {
+                char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+                *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+                g_free (name);
+       }
+
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
-       if (code_size)
-               *code_size = code - start;
 
        return start;
 }
@@ -796,19 +803,15 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0);
+       res = g_slist_prepend (res, info);
 
        for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+               get_delegate_invoke_impl (&info, FALSE, i);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -833,10 +836,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        return cached;
                }
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL);
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0);
+                       mono_tramp_info_register (info, NULL);
+               }
                cached = start;
                mono_mini_arch_unlock ();
                return cached;
@@ -862,7 +868,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+                       mono_tramp_info_register (info, NULL);
                }
                cache [sig->param_count] = start;
                mono_mini_arch_unlock ();
@@ -1508,8 +1516,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                        cinfo->ret.reg = ARMREG_R0;
                        break;
                }
-               // FIXME: Only for variable types
-               if (mini_is_gsharedvt_type (t)) {
+               if (mini_is_gsharedvt_variable_type (t)) {
                        cinfo->ret.storage = RegTypeStructByAddr;
                        break;
                }
@@ -1627,7 +1634,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                                add_general (&gr, &stack_size, ainfo, TRUE);
                                break;
                        }
-                       if (mini_is_gsharedvt_type (t)) {
+                       if (mini_is_gsharedvt_variable_type (t)) {
                                /* gsharedvt arguments are passed by ref */
                                g_assert (mini_is_gsharedvt_type (t));
                                add_general (&gr, &stack_size, ainfo, TRUE);
@@ -2802,8 +2809,8 @@ dyn_call_supported (CallInfo *cinfo, MonoMethodSignature *sig)
 
                switch (ainfo->storage) {
                case RegTypeGeneral:
-                       break;
                case RegTypeIRegPair:
+               case RegTypeBaseGen:
                        break;
                case RegTypeBase:
                        if (ainfo->offset >= (DYN_CALL_STACK_ARGS * sizeof (gpointer)))
@@ -2918,12 +2925,16 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
                ArgInfo *ainfo = &dinfo->cinfo->args [i + sig->hasthis];
                int slot = -1;
 
-               if (ainfo->storage == RegTypeGeneral || ainfo->storage == RegTypeIRegPair || ainfo->storage == RegTypeStructByVal)
+               if (ainfo->storage == RegTypeGeneral || ainfo->storage == RegTypeIRegPair || ainfo->storage == RegTypeStructByVal) {
                        slot = ainfo->reg;
-               else if (ainfo->storage == RegTypeBase)
+               } else if (ainfo->storage == RegTypeBase) {
                        slot = PARAM_REGS + (ainfo->offset / 4);
-               else
+               } else if (ainfo->storage == RegTypeBaseGen) {
+                       /* slot + 1 is the first stack slot, so the code below will work */
+                       slot = 3;
+               } else {
                        g_assert_not_reached ();
+               }
 
                if (t->byref) {
                        p->regs [slot] = (mgreg_t)*arg;
@@ -3892,6 +3903,10 @@ handle_thunk (MonoCompile *cfg, MonoDomain *domain, guchar *code, const guchar *
                                        /* Free entry */
                                        target_thunk = p;
                                        break;
+                               } else if (((guint32*)p) [2] == (guint32)target) {
+                                       /* Thunk already points to target */
+                                       target_thunk = p;
+                                       break;
                                }
                        }
                }
@@ -5968,6 +5983,22 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ins->backend.pc_offset = code - cfg->native_code;
                        bb->spill_slot_defs = g_slist_prepend_mempool (cfg->mempool, bb->spill_slot_defs, ins);
                        break;
+               case OP_GC_SAFE_POINT: {
+#if defined (USE_COOP_GC)
+                       const char *polling_func = NULL;
+                       guint8 *buf [1];
+
+                       polling_func = "mono_threads_state_poll";
+                       ARM_LDR_IMM (code, ARMREG_IP, ins->sreg1, 0);
+                       ARM_CMP_REG_IMM (code, ARMREG_IP, 0, 0);
+                       buf [0] = code;
+                       ARM_B_COND (code, ARMCOND_EQ, 0);
+                       mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, polling_func);
+                       code = emit_call_seq (cfg, code);
+                       arm_patch (buf [0], code);
+#endif
+                       break;
+               }
 
                default:
                        g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
@@ -6003,6 +6034,27 @@ mono_arch_register_lowlevel_calls (void)
                if (mono_arm_have_fast_tls ()) {
                        mono_register_jit_icall (mono_fast_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
                        mono_register_jit_icall (mono_fast_set_tls_key, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
+
+                       mono_tramp_info_register (
+                               mono_tramp_info_create (
+                                       "mono_get_tls_key",
+                                       (guint8*)mono_fast_get_tls_key,
+                                       (guint8*)mono_fast_get_tls_key_end - (guint8*)mono_fast_get_tls_key,
+                                       NULL,
+                                       mono_arch_get_cie_program ()
+                                       ),
+                               NULL
+                               );
+                       mono_tramp_info_register (
+                               mono_tramp_info_create (
+                                       "mono_set_tls_key",
+                                       (guint8*)mono_fast_set_tls_key,
+                                       (guint8*)mono_fast_set_tls_key_end - (guint8*)mono_fast_set_tls_key,
+                                       NULL,
+                                       mono_arch_get_cie_program ()
+                                       ),
+                               NULL
+                               );
                } else {
                        g_warning ("No fast tls on device. Using fallbacks.");
                        mono_register_jit_icall (mono_fallback_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
@@ -6140,10 +6192,10 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                 * FIXME: Optimize this.
                 */
                ARM_PUSH (code, (1 << ARMREG_R7) | (1 << ARMREG_LR));
-               ARM_MOV_REG_REG (code, ARMREG_R7, ARMREG_SP);
                prev_sp_offset += 8; /* r7 and lr */
                mono_emit_unwind_op_def_cfa_offset (cfg, code, prev_sp_offset);
                mono_emit_unwind_op_offset (cfg, code, ARMREG_R7, (- prev_sp_offset) + 0);
+               ARM_MOV_REG_REG (code, ARMREG_R7, ARMREG_SP);
        }
 
        if (!method->save_lmf) {
@@ -6607,6 +6659,9 @@ mono_arch_emit_epilog (MonoCompile *cfg)
         */
        code = cfg->native_code + cfg->code_len;
 
+       /* Save the uwind state which is needed by the out-of-line code */
+       mono_emit_unwind_op_remember_state (cfg, code);
+
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) {
                code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, code, TRUE);
        }
@@ -6642,7 +6697,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        }
 
        if (method->save_lmf) {
-               int lmf_offset, reg, sp_adj, regmask;
+               int lmf_offset, reg, sp_adj, regmask, nused_int_regs = 0;
                /* all but r0-r3, sp and pc */
                pos += sizeof (MonoLMF) - (MONO_ARM_NUM_SAVED_REGS * sizeof (mgreg_t));
                lmf_offset = pos;
@@ -6664,15 +6719,33 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                        regmask &= ~(1 << ARMREG_PC);
                /* point sp at the registers to restore: 10 is 14 -4, because we skip r0-r3 */
                code = emit_big_add (code, ARMREG_SP, cfg->frame_reg, cfg->stack_usage - lmf_offset + sp_adj);
+               for (i = 0; i < 16; i++) {
+                       if (regmask & (1 << i))
+                               nused_int_regs ++;
+               }
+               mono_emit_unwind_op_def_cfa (cfg, code, ARMREG_SP, ((iphone_abi ? 3 : 0) + nused_int_regs) * 4);
                /* restore iregs */
                ARM_POP (code, regmask); 
                if (iphone_abi) {
+                       for (i = 0; i < 16; i++) {
+                               if (regmask & (1 << i))
+                                       mono_emit_unwind_op_same_value (cfg, code, i);
+                       }
                        /* Restore saved r7, restore LR to PC */
                        /* Skip lr from the lmf */
+                       mono_emit_unwind_op_def_cfa_offset (cfg, code, 3 * 4);
                        ARM_ADD_REG_IMM (code, ARMREG_SP, ARMREG_SP, sizeof (gpointer), 0);
+                       mono_emit_unwind_op_def_cfa_offset (cfg, code, 2 * 4);
                        ARM_POP (code, (1 << ARMREG_R7) | (1 << ARMREG_PC));
                }
        } else {
+               int i, nused_int_regs = 0;
+
+               for (i = 0; i < 16; i++) {
+                       if (cfg->used_int_regs & (1 << i))
+                               nused_int_regs ++;
+               }
+
                if ((i = mono_arm_is_rotated_imm8 (cfg->stack_usage, &rot_amount)) >= 0) {
                        ARM_ADD_REG_IMM (code, ARMREG_SP, cfg->frame_reg, i, rot_amount);
                } else {
@@ -6680,17 +6753,32 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                        ARM_ADD_REG_REG (code, ARMREG_SP, cfg->frame_reg, ARMREG_IP);
                }
 
+               if (cfg->frame_reg != ARMREG_SP) {
+                       mono_emit_unwind_op_def_cfa_reg (cfg, code, ARMREG_SP);
+               }
+
                if (iphone_abi) {
                        /* Restore saved gregs */
-                       if (cfg->used_int_regs)
+                       if (cfg->used_int_regs) {
+                               mono_emit_unwind_op_def_cfa_offset (cfg, code, (2 + nused_int_regs) * 4);
                                ARM_POP (code, cfg->used_int_regs);
+                               for (i = 0; i < 16; i++) {
+                                       if (cfg->used_int_regs & (1 << i))
+                                               mono_emit_unwind_op_same_value (cfg, code, i);
+                               }
+                       }
+                       mono_emit_unwind_op_def_cfa_offset (cfg, code, 2 * 4);
                        /* Restore saved r7, restore LR to PC */
                        ARM_POP (code, (1 << ARMREG_R7) | (1 << ARMREG_PC));
                } else {
+                       mono_emit_unwind_op_def_cfa_offset (cfg, code, (nused_int_regs + 1) * 4);
                        ARM_POP (code, cfg->used_int_regs | (1 << ARMREG_PC));
                }
        }
 
+       /* Restore the unwind state to be the same as before the epilog */
+       mono_emit_unwind_op_restore_state (cfg, code);
+
        cfg->code_len = code - cfg->native_code;
 
        g_assert (cfg->code_len < cfg->code_size);
@@ -6845,6 +6933,16 @@ mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
        return (MonoVTable*) regs [MONO_ARCH_RGCTX_REG];
 }
 
+GSList*
+mono_arch_get_cie_program (void)
+{
+       GSList *l = NULL;
+
+       mono_add_unwind_op_def_cfa (l, (guint8*)NULL, (guint8*)NULL, ARMREG_SP, 0);
+
+       return l;
+}
+
 /* #define ENABLE_WRONG_METHOD_CHECK 1 */
 #define BASE_SIZE (6 * 4)
 #define BSEARCH_ENTRY_SIZE (4 * 4)
@@ -6913,6 +7011,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 #ifdef ENABLE_WRONG_METHOD_CHECK
        char * cond;
 #endif
+       GSList *unwind_ops;
 
        size = BASE_SIZE;
 #ifdef USE_JUMP_TABLES
@@ -6967,6 +7066,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                code = mono_domain_code_reserve (domain, size);
        start = code;
 
+       unwind_ops = mono_arch_get_cie_program ();
+
 #ifdef DEBUG_IMT
        g_print ("Building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p fail_tramp %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable, fail_tramp);
        for (i = 0; i < count; ++i) {
@@ -6977,6 +7078,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 
 #ifdef USE_JUMP_TABLES
        ARM_PUSH3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 3 * sizeof (mgreg_t));
 #define VTABLE_JTI 0
 #define IMT_METHOD_OFFSET 0
 #define TARGET_CODE_OFFSET 1
@@ -6991,10 +7093,13 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R2, VTABLE_JTI);
        set_jumptable_element (jte, VTABLE_JTI, vtable);
 #else
-       if (large_offsets)
+       if (large_offsets) {
                ARM_PUSH4 (code, ARMREG_R0, ARMREG_R1, ARMREG_IP, ARMREG_PC);
-       else
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 4 * sizeof (mgreg_t));
+       } else {
                ARM_PUSH2 (code, ARMREG_R0, ARMREG_R1);
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 2 * sizeof (mgreg_t));
+       }
        ARM_LDR_IMM (code, ARMREG_R0, ARMREG_LR, -4);
        vtable_target = code;
        ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
@@ -7067,6 +7172,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, target_code_jti, ARMCOND_AL);
                                /* Restore registers */
                                ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+                               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
                                /*  And branch */
                                ARM_BX (code, ARMREG_R1);
                                set_jumptable_element (jte, target_code_jti, item->value.target_code);
@@ -7098,6 +7204,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                        ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_IP, ARMREG_R1);
                                        /* Restore registers and branch */
                                        ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+                                       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
                                        ARM_BX (code, ARMREG_IP);
 #else
                                        vtable_offset_ins = code;
@@ -7114,11 +7221,15 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 #ifdef USE_JUMP_TABLES
                                        ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, vtable_offset);
                                        ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+                                       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
                                        ARM_BX (code, ARMREG_IP);
 #else
                                        ARM_POP2 (code, ARMREG_R0, ARMREG_R1);
-                                       if (large_offsets)
+                                       if (large_offsets) {
+                                               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 2 * sizeof (mgreg_t));
                                                ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 2 * sizeof (gpointer));
+                                       }
+                                       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
                                        ARM_LDR_IMM (code, ARMREG_PC, ARMREG_IP, vtable_offset);
 #endif
                                }
@@ -7132,6 +7243,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, target_code_jti, ARMCOND_AL);
                                /* Restore registers */
                                ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+                               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
                                /* And branch */
                                ARM_BX (code, ARMREG_R1);
                                set_jumptable_element (jte, target_code_jti, fail_tramp);
@@ -7231,6 +7343,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        mono_stats.imt_thunks_size += code - start;
 
        g_assert (DISTANCE (start, code) <= size);
+
+       mono_tramp_info_register (mono_tramp_info_create (NULL, (guint8*)start, DISTANCE (start, code), NULL, unwind_ops), domain);
+
        return start;
 }
 
index cb7a975f9d1d36bbc8876f9f33e83b32f019e062..309ebd82531bf937c0f302cc1955da251b7f8435 100644 (file)
@@ -239,23 +239,30 @@ mono_runtime_install_handlers (void)
 pid_t
 mono_runtime_syscall_fork ()
 {
+#ifdef HAVE_FORK
        return (pid_t) fork ();
+#else
+       g_assert_not_reached ();
+#endif
 }
 
 void
 mono_gdb_render_native_backtraces (pid_t crashed_pid)
 {
+#ifdef HAVE_EXECV
        const char *argv [5];
        char template [] = "/tmp/mono-gdb-commands.XXXXXX";
        FILE *commands;
        gboolean using_lldb = FALSE;
 
+       using_lldb = TRUE;
+
        argv [0] = g_find_program_in_path ("gdb");
-       if (!argv [0]) {
-               // FIXME: LLDB doesn't quit when given the 'quit' command
-               //argv [0] = g_find_program_in_path ("lldb");
-               //using_lldb = TRUE;
-       }
+       if (argv [0])
+               using_lldb = FALSE;
+
+       if (using_lldb)
+               argv [0] = g_find_program_in_path ("lldb");
 
        if (argv [0] == NULL)
                return;
@@ -277,6 +284,7 @@ mono_gdb_render_native_backtraces (pid_t crashed_pid)
        } else {
                fprintf (commands, "attach %ld\n", (long) crashed_pid);
                fprintf (commands, "info threads\n");
+               fprintf (commands, " t a a info thread\n");
                fprintf (commands, "thread apply all bt\n");
                argv [1] = "-batch";
                argv [2] = "-x";
@@ -286,8 +294,13 @@ mono_gdb_render_native_backtraces (pid_t crashed_pid)
        fflush (commands);
        fclose (commands);
 
+       fclose (stdin);
+
        execv (argv [0], (char**)argv);
        unlink (template);
+#else
+       fprintf (stderr, "mono_gdb_render_native_backtraces not supported on this platform\n");
+#endif // HAVE_EXECV
 }
 
 gboolean
index 5937e45464ddab96661b29795cef6441c8b49eb7..fd607d71f4397a9742c42d61a649a7878f220829 100644 (file)
@@ -53,6 +53,7 @@
 #include <mono/metadata/profiler.h>
 #include <mono/metadata/mono-endian.h>
 #include <mono/metadata/environment.h>
+#include <mono/metadata/mono-mlist.h>
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-logger-internal.h>
 
@@ -98,13 +99,13 @@ mono_exceptions_init (void)
                MonoTrampInfo *info;
 
                restore_context_func = mono_arch_get_restore_context (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                call_filter_func = mono_arch_get_call_filter (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                throw_exception_func = mono_arch_get_throw_exception (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                rethrow_exception_func = mono_arch_get_rethrow_exception (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
        }
 #ifdef MONO_ARCH_HAVE_RESTORE_STACK_SUPPORT
        try_more_restore_tramp = mono_create_specific_trampoline (try_more_restore, MONO_TRAMPOLINE_RESTORE_STACK_PROT, mono_domain_get (), NULL);
@@ -165,7 +166,7 @@ mono_get_throw_corlib_exception (void)
                code = mono_aot_get_trampoline ("throw_corlib_exception");
        else {
                code = mono_arch_get_throw_corlib_exception (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
        }
 
        mono_memory_barrier ();
@@ -243,6 +244,8 @@ find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, Mo
                if (managed)
                        *managed = TRUE;
                return frame.ji;
+       case FRAME_TYPE_TRAMPOLINE:
+               return frame.ji;
        case FRAME_TYPE_MANAGED_TO_NATIVE:
                if (frame.ji)
                        return frame.ji;
@@ -301,10 +304,10 @@ mono_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *re
        if (ji == (gpointer)-1)
                return ji;
 
-       if (ji)
+       if (ji && !ji->is_trampoline)
                method = jinfo_get_method (ji);
 
-       if (managed2 || (ji && method->wrapper_type)) {
+       if (managed2 || (method && method->wrapper_type)) {
                const char *real_ip, *start;
                gint32 offset;
 
@@ -397,7 +400,7 @@ mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
                *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~(SIZEOF_VOID_P -1));
        }
 
-       if (frame->ji && !frame->ji->async)
+       if (frame->ji && !frame->ji->is_trampoline && !frame->ji->async)
                method = jinfo_get_method (frame->ji);
 
        if (frame->type == FRAME_TYPE_MANAGED && method) {
@@ -451,6 +454,9 @@ mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
        return TRUE;
 }
 
+/*
+ * This function is async-safe.
+ */
 static gpointer
 get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx)
 {
@@ -615,50 +621,6 @@ mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpoin
        return len > 0;
 }
 
-MonoString *
-ves_icall_System_Exception_get_trace (MonoException *ex)
-{
-       MonoDomain *domain = mono_domain_get ();
-       MonoString *res;
-       MonoArray *ta = ex->trace_ips;
-       int i, len;
-       GString *trace_str;
-
-       if (ta == NULL)
-               /* Exception is not thrown yet */
-               return NULL;
-
-       len = mono_array_length (ta) >> 1;
-       trace_str = g_string_new ("");
-       for (i = 0; i < len; i++) {
-               MonoJitInfo *ji;
-               gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0);
-               gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1);
-
-               ji = mono_jit_info_table_find (domain, ip);
-               if (ji == NULL) {
-                       /* Unmanaged frame */
-                       g_string_append_printf (trace_str, "in (unmanaged) %p\n", ip);
-               } else {
-                       gchar *location;
-                       gint32 address;
-                       MonoMethod *method = get_method_from_stack_frame (ji, generic_info);
-
-                       address = (char *)ip - (char *)ji->code_start;
-                       location = mono_debug_print_stack_frame (
-                               method, address, ex->object.vtable->domain);
-
-                       g_string_append_printf (trace_str, "%s\n", location);
-                       g_free (location);
-               }
-       }
-
-       res = mono_string_new (ex->object.vtable->domain, trace_str->str);
-       g_string_free (trace_str, TRUE);
-
-       return res;
-}
-
 MonoArray *
 ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
 {
@@ -808,6 +770,10 @@ mono_walk_stack_with_state (MonoJitStackWalk func, MonoThreadUnwindState *state,
 
        g_assert (state->valid);
 
+       if (!state->unwind_data [MONO_UNWIND_DATA_DOMAIN])
+               /* Not attached */
+               return;
+
        mono_walk_stack_full (func,
                &state->ctx, 
                state->unwind_data [MONO_UNWIND_DATA_DOMAIN],
@@ -870,7 +836,7 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
                if (!res)
                        return;
 
-               if ((unwind_options & MONO_UNWIND_LOOKUP_IL_OFFSET) && frame.ji) {
+               if ((unwind_options & MONO_UNWIND_LOOKUP_IL_OFFSET) && frame.ji && !frame.ji->is_trampoline) {
                        MonoDebugSourceLocation *source;
 
                        source = mono_debug_lookup_source_location (jinfo_get_method (frame.ji), frame.native_offset, domain);
@@ -889,7 +855,7 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
 
                frame.il_offset = il_offset;
 
-               if ((unwind_options & MONO_UNWIND_LOOKUP_ACTUAL_METHOD) && frame.ji) {
+               if ((unwind_options & MONO_UNWIND_LOOKUP_ACTUAL_METHOD) && frame.ji && !frame.ji->is_trampoline) {
                        frame.actual_method = get_method_from_stack_frame (frame.ji, get_generic_info_from_stack_frame (frame.ji, &ctx));
                } else {
                        frame.actual_method = frame.method;
@@ -944,7 +910,9 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
                if (!res)
                        return FALSE;
 
-               if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE || frame.type == FRAME_TYPE_DEBUGGER_INVOKE)
+               if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE ||
+                               frame.type == FRAME_TYPE_DEBUGGER_INVOKE ||
+                               frame.type == FRAME_TYPE_TRAMPOLINE)
                        continue;
 
                ji = frame.ji;
@@ -1085,7 +1053,7 @@ mini_jit_info_table_find_ext (MonoDomain *domain, char *addr, gboolean allow_tra
 MonoJitInfo*
 mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domain)
 {
-       return mini_jit_info_table_find_ext (domain, addr, FALSE, out_domain);
+       return mini_jit_info_table_find_ext (domain, addr, TRUE, out_domain);
 }
 
 /*
@@ -1183,18 +1151,42 @@ build_native_trace (void)
 #endif
 }
 
-#define setup_managed_stacktrace_information() do {    \
-       if (mono_ex && !initial_trace_ips) {    \
-               trace_ips = g_list_reverse (trace_ips); \
-               MONO_OBJECT_SETREF (mono_ex, trace_ips, glist_to_array (trace_ips, mono_defaults.int_class));   \
-               MONO_OBJECT_SETREF (mono_ex, native_trace_ips, build_native_trace ());  \
-               if (has_dynamic_methods)        \
-                       /* These methods could go away anytime, so compute the stack trace now */       \
-                       MONO_OBJECT_SETREF (mono_ex, stack_trace, ves_icall_System_Exception_get_trace (mono_ex));      \
-       }       \
-       g_list_free (trace_ips);        \
-       trace_ips = NULL;       \
-} while (0)
+static void
+setup_stack_trace (MonoException *mono_ex, GSList *dynamic_methods, MonoArray *initial_trace_ips, GList **trace_ips)
+{
+       if (mono_ex && !initial_trace_ips) {
+               *trace_ips = g_list_reverse (*trace_ips);
+               MONO_OBJECT_SETREF (mono_ex, trace_ips, glist_to_array (*trace_ips, mono_defaults.int_class));
+               MONO_OBJECT_SETREF (mono_ex, native_trace_ips, build_native_trace ());
+               if (dynamic_methods) {
+                       /* These methods could go away anytime, so save a reference to them in the exception object */
+                       GSList *l;
+                       MonoMList *list = NULL;
+
+                       for (l = dynamic_methods; l; l = l->next) {
+                               gpointer *dis_link;
+                               MonoDomain *domain = mono_domain_get ();
+
+                               if (domain->method_to_dyn_method) {
+                                       mono_domain_lock (domain);
+                                       dis_link = g_hash_table_lookup (domain->method_to_dyn_method, l->data);
+                                       mono_domain_unlock (domain);
+                                       if (dis_link) {
+                                               MonoObject *o = mono_gc_weak_link_get (dis_link);
+                                               if (o) {
+                                                       list = mono_mlist_prepend (list, o);
+                                               }
+                                       }
+                               }
+                       }
+
+                       MONO_OBJECT_SETREF (mono_ex, dynamic_methods, list);
+               }
+       }
+       g_list_free (*trace_ips);
+       *trace_ips = NULL;
+}
+
 /*
  * mono_handle_exception_internal_first_pass:
  *
@@ -1212,12 +1204,12 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
        MonoLMF *lmf = mono_get_lmf ();
        MonoArray *initial_trace_ips = NULL;
        GList *trace_ips = NULL;
+       GSList *dynamic_methods = NULL;
        MonoException *mono_ex;
        gboolean stack_overflow = FALSE;
        MonoContext initial_ctx;
        MonoMethod *method;
        int frame_count = 0;
-       gboolean has_dynamic_methods = FALSE;
        gint32 filter_idx;
        int i;
        MonoObject *ex_obj;
@@ -1265,7 +1257,9 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
 
                unwind_res = mono_find_jit_info_ext (domain, jit_tls, NULL, ctx, &new_ctx, NULL, &lmf, NULL, &frame);
                if (unwind_res) {
-                       if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE || frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) {
+                       if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE ||
+                                       frame.type == FRAME_TYPE_MANAGED_TO_NATIVE ||
+                                       frame.type == FRAME_TYPE_TRAMPOLINE) {
                                *ctx = new_ctx;
                                continue;
                        }
@@ -1274,7 +1268,8 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
                }
 
                if (!unwind_res) {
-                       setup_managed_stacktrace_information ();
+                       setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+                       g_slist_free (dynamic_methods);
                        return FALSE;
                }
 
@@ -1302,7 +1297,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
                }
 
                if (method->dynamic)
-                       has_dynamic_methods = TRUE;
+                       dynamic_methods = g_slist_prepend (dynamic_methods, method);
 
                if (stack_overflow) {
                        if (DOES_STACK_GROWS_UP)
@@ -1349,7 +1344,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
                                        FIXME Not 100% sure if it's a good idea even with user clauses.
                                        */
                                        if (is_user_frame)
-                                               setup_managed_stacktrace_information ();
+                                               setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
 
 #ifdef MONO_CONTEXT_SET_LLVM_EXC_REG
                                        if (ji->from_llvm)
@@ -1385,7 +1380,8 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
 
                                        if (filtered) {
                                                if (!is_user_frame)
-                                                       setup_managed_stacktrace_information ();
+                                                       setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+                                               g_slist_free (dynamic_methods);
                                                /* mono_debugger_agent_handle_exception () needs this */
                                                MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
                                                return TRUE;
@@ -1393,7 +1389,8 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
                                }
 
                                if (ei->flags == MONO_EXCEPTION_CLAUSE_NONE && mono_object_isinst (ex_obj, catch_class)) {
-                                       setup_managed_stacktrace_information ();
+                                       setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+                                       g_slist_free (dynamic_methods);
 
                                        if (out_ji)
                                                *out_ji = ji;
@@ -1602,7 +1599,9 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
 
                        unwind_res = mono_find_jit_info_ext (domain, jit_tls, NULL, ctx, &new_ctx, NULL, &lmf, NULL, &frame);
                        if (unwind_res) {
-                               if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE || frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) {
+                               if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE ||
+                                               frame.type == FRAME_TYPE_MANAGED_TO_NATIVE ||
+                                               frame.type == FRAME_TYPE_TRAMPOLINE) {
                                        *ctx = new_ctx;
                                        continue;
                                }
@@ -1731,8 +1730,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
 
                                        return 0;
                                }
-                               if (is_address_protected (ji, ei, MONO_CONTEXT_GET_IP (ctx)) &&
-                                       (ei->flags == MONO_EXCEPTION_CLAUSE_FAULT)) {
+                               if (ei->flags == MONO_EXCEPTION_CLAUSE_FAULT) {
                                        if (mono_trace_is_enabled () && mono_trace_eval (method))
                                                g_print ("EXCEPTION: fault clause %d of %s\n", i, mono_method_full_name (method, TRUE));
                                        jit_tls->orig_ex_ctx_set = TRUE;
@@ -1740,8 +1738,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
                                        jit_tls->orig_ex_ctx_set = FALSE;
                                        call_filter (ctx, ei->handler_start);
                                }
-                               if (is_address_protected (ji, ei, MONO_CONTEXT_GET_IP (ctx)) &&
-                                       (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
+                               if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
                                        if (mono_trace_is_enabled () && mono_trace_eval (method))
                                                g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (method, TRUE));
                                        jit_tls->orig_ex_ctx_set = TRUE;
@@ -2044,7 +2041,7 @@ print_overflow_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer da
        PrintOverflowUserData *user_data = data;
        gchar *location;
 
-       if (frame->ji)
+       if (frame->ji && frame->type != FRAME_TYPE_TRAMPOLINE)
                method = jinfo_get_method (frame->ji);
 
        if (method) {
@@ -2097,7 +2094,7 @@ mono_handle_hard_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx,
 
        mono_walk_stack_with_ctx (print_overflow_stack_frame, &mctx, MONO_UNWIND_LOOKUP_ACTUAL_METHOD, &ud);
 #else
-       if (ji && jinfo_get_method (ji))
+       if (ji && !ji->is_trampoline && jinfo_get_method (ji))
                mono_runtime_printf_err ("At %s", mono_method_full_name (jinfo_get_method (ji), TRUE));
        else
                mono_runtime_printf_err ("At <unmanaged>.");
@@ -2111,7 +2108,7 @@ print_stack_frame_to_stderr (StackFrameInfo *frame, MonoContext *ctx, gpointer d
 {
        MonoMethod *method = NULL;
 
-       if (frame->ji)
+       if (frame->ji && frame->type != FRAME_TYPE_TRAMPOLINE)
                method = jinfo_get_method (frame->ji);
 
        if (method) {
@@ -2130,7 +2127,7 @@ print_stack_frame_to_string (StackFrameInfo *frame, MonoContext *ctx, gpointer d
        GString *p = (GString*)data;
        MonoMethod *method = NULL;
 
-       if (frame->ji)
+       if (frame->ji && frame->type != FRAME_TYPE_TRAMPOLINE)
                method = jinfo_get_method (frame->ji);
 
        if (method && frame->domain) {
@@ -2526,20 +2523,16 @@ mono_thread_state_init_from_sigctx (MonoThreadUnwindState *ctx, void *sigctx)
                return FALSE;
        }
 
-       if (sigctx)
+       if (sigctx) {
                mono_sigctx_to_monoctx (sigctx, &ctx->ctx);
-       else
-#if defined(MONO_CROSS_COMPILE)
-               ctx->valid = FALSE; //A cross compiler doesn't need to suspend.
-#elif MONO_ARCH_HAS_MONO_CONTEXT
-               MONO_CONTEXT_GET_CURRENT (ctx->ctx);
-#else
-               g_error ("Use a null sigctx requires a working mono-context");
-#endif
 
-       ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
-       ctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
-       ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = thread->jit_data;
+               ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
+               ctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
+               ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = thread->jit_data;
+       }
+       else {
+               mono_thread_state_init (ctx);
+       }
 
        if (!ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] || !ctx->unwind_data [MONO_UNWIND_DATA_LMF])
                return FALSE;
@@ -2552,6 +2545,26 @@ mono_thread_state_init_from_sigctx (MonoThreadUnwindState *ctx, void *sigctx)
 #endif
 }
 
+void
+mono_thread_state_init (MonoThreadUnwindState *ctx)
+{
+       MonoThreadInfo *thread = mono_thread_info_current_unchecked ();
+
+#if defined(MONO_CROSS_COMPILE)
+       ctx->valid = FALSE; //A cross compiler doesn't need to suspend.
+#elif MONO_ARCH_HAS_MONO_CONTEXT
+       MONO_CONTEXT_GET_CURRENT (ctx->ctx);
+#else
+       g_error ("Use a null sigctx requires a working mono-context");
+#endif
+
+       ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
+       ctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
+       ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = thread ? thread->jit_data : NULL;
+       ctx->valid = TRUE;
+}
+
+
 gboolean
 mono_thread_state_init_from_monoctx (MonoThreadUnwindState *ctx, MonoContext *mctx)
 {
index 3d24b46d082e9d3b49bc0b4293b660efb11b20f4..27a36204ca0c354e2448695293162924744d88c8 100644 (file)
@@ -821,6 +821,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                ji = frame.ji;
 
                // FIXME: For skipped frames, scan the param area of the parent frame conservatively ?
+               // FIXME: trampolines
 
                if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) {
                        /*
index d3e3f9338cc50e871d5b50a967790b7e5286016e..e1ca51ba9806b76ac01465f7ad6d8b5f0638ea26 100644 (file)
@@ -4618,6 +4618,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 
        mono_stats.imt_thunks_size += size;
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, size, NULL, NULL), domain);
+
        return start;
 }
 
index 7e3522613f4daf6333429daf2bf7558e6f02972b..f894a7721648c58e1f40e1f0556a192aec0923c6 100644 (file)
@@ -648,11 +648,7 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
   // EngineBuilder no longer has a copy assignment operator (?)
   std::unique_ptr<Module> Owner(unwrap(MP));
   EngineBuilder b (std::move(Owner));
-#ifdef TARGET_AMD64
-  ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).setCodeModel (CodeModel::Large).create ();
-#else
   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
-#endif
 
   g_assert (EE);
   mono_ee->EE = EE;
index d98c658f4c446d0d99f34a19e72042d3b80c5347..ee281f871157c9c5538aaad068bb2a874cb59e5a 100644 (file)
@@ -45,7 +45,7 @@ void bzero (void *to, size_t count) { memset (to, 0, count); }
   */
 typedef struct {
        LLVMModuleRef module;
-       LLVMValueRef throw, rethrow, throw_corlib_exception;
+       LLVMValueRef throw, rethrow, throw_corlib_exception, state_poll;
        GHashTable *llvm_types;
        LLVMValueRef got_var;
        const char *got_symbol;
@@ -1186,6 +1186,9 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
 
                                members [0] = IntPtrType ();
                                ret_type = LLVMStructType (members, 1, FALSE);
+                       } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
+                               /* Empty struct */
+                               ret_type = LLVMVoidType ();
                        } else {
                                g_assert_not_reached ();
                        }
@@ -2252,14 +2255,6 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
        ;
 }
 
-/* Have to export this for AOT */
-void
-mono_personality (void)
-{
-       /* Not used */
-       g_assert_not_reached ();
-}
-
 static void
 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
 {
@@ -2546,6 +2541,10 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                case LLVMArgVtypeInReg: {
                        LLVMValueRef regs [2];
 
+                       if (LLVMTypeOf (lcall) == LLVMVoidType ())
+                               /* Empty struct */
+                               break;
+
                        if (!addresses [ins->dreg])
                                addresses [ins->dreg] = build_alloca (ctx, sig->ret);
 
@@ -2622,7 +2621,7 @@ emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder
 
        if (cfg->compile_aot) {
                /* Use a dummy personality function */
-               personality = LLVMGetNamedFunction (module, "mono_aot_personality");
+               personality = LLVMGetNamedFunction (module, "mono_personality");
                g_assert (personality);
        } else {
                personality = LLVMGetNamedFunction (module, "mono_personality");
@@ -2759,7 +2758,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
        if (bb->flags & BB_EXCEPTION_HANDLER) {
                if (!bblocks [bb->block_num].invoke_target) {
-                       //LLVM_FAILURE (ctx, "handler without invokes");
+                       LLVM_FAILURE (ctx, "handler without invokes");
                }
 
                emit_handler_start (ctx, bb, builder);
@@ -4726,6 +4725,61 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                case OP_DUMMY_USE:
                        break;
+               case OP_GC_SAFE_POINT: {
+                       LLVMValueRef callee, cmp, val;
+                       LLVMTypeRef llvm_sig;
+                       const char *icall_name;
+                       LLVMBasicBlockRef poll_bb, cont_bb;
+
+                       poll_bb = gen_bb (ctx, "POLL_BB");
+                       cont_bb = gen_bb (ctx, "NOPOLL_BB");
+
+                       val = LLVMBuildLoad (ctx->builder, convert (ctx, lhs, LLVMPointerType (LLVMInt8Type (), 0)), "");
+                       cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstInt (LLVMTypeOf (val), 0, FALSE), "");
+                       LLVMBuildCondBr (ctx->builder, cmp, cont_bb, poll_bb);
+
+                       builder = ctx->builder = create_builder (ctx);
+                       LLVMPositionBuilderAtEnd (builder, poll_bb);
+
+                       MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
+                       sig->ret = &mono_get_void_class ()->byval_arg;
+                       icall_name = "mono_threads_state_poll";
+                       llvm_sig = sig_to_llvm_sig (ctx, sig);
+
+                       if (ctx->cfg->compile_aot) {
+                               callee = ctx->lmodule->state_poll;
+                               if (!callee) {
+                                       MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
+                                       sig->ret = &mono_get_void_class ()->byval_arg;
+                                       llvm_sig = sig_to_llvm_sig (ctx, sig);
+
+                                       callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
+                               }
+                       } else {
+                               callee = ctx->lmodule->state_poll;
+                               if (!callee) {
+                                       MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
+                                       sig->ret = &mono_get_void_class ()->byval_arg;
+                                       llvm_sig = sig_to_llvm_sig (ctx, sig);
+
+                                       callee = LLVMAddFunction (ctx->module, icall_name, llvm_sig);
+                                       LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
+                                       ctx->lmodule->state_poll = callee;
+                               }
+                       }
+                       //
+                       // FIXME: This can use the PreserveAll cconv to avoid clobbering registers.
+                       // It requires the wrapper to also use that calling convention.
+                       //
+                       val = emit_call (ctx, bb, &builder, callee, NULL, 0);
+                       LLVMBuildBr (builder, cont_bb);
+
+                       builder = ctx->builder = create_builder (ctx);
+                       LLVMPositionBuilderAtEnd (builder, cont_bb);
+
+                       bblocks [bb->block_num].end_bblock = cont_bb;
+                       break;
+               }
 
                        /*
                         * EXCEPTION HANDLING
@@ -6015,21 +6069,6 @@ mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix,
                LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
        }
 
-       /* Add a dummy personality function */
-       {
-               LLVMBasicBlockRef lbb;
-               LLVMBuilderRef lbuilder;
-               LLVMValueRef personality;
-
-               personality = LLVMAddFunction (lmodule->module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
-               LLVMSetLinkage (personality, LLVMInternalLinkage);
-               lbb = LLVMAppendBasicBlock (personality, "BB0");
-               lbuilder = LLVMCreateBuilder ();
-               LLVMPositionBuilderAtEnd (lbuilder, lbb);
-               LLVMBuildRetVoid (lbuilder);
-               mark_as_used (lmodule, personality);
-       }
-
        lmodule->llvm_types = g_hash_table_new (NULL, NULL);
        lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
        lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
index 4c18cc970ee5a77df3e3444edc6e00b5348872fa..362fa3a14bac36bfaf82a57b24611e83821e706b 100644 (file)
@@ -544,7 +544,7 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit
 #define MAX_ARCH_DELEGATE_PARAMS (4 - 1)
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count)
 {
        guint8 *code, *start;
 
@@ -579,8 +579,13 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
                mono_arch_flush_icache (start, size);
        }
 
-       if (code_size)
-               *code_size = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+               g_free (name);
+       }
 
        return start;
 }
@@ -595,19 +600,15 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0);
+       res = g_slist_prepend (res, info);
 
        for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+               get_delegate_invoke_impl (&info, FALSE, i);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -630,10 +631,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        return cached;
                }
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL);
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0);
+                       mono_tramp_info_register (info, NULL);
+               }
                cached = start;
                mono_mini_arch_unlock ();
                return cached;
@@ -659,7 +663,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+                       mono_tramp_info_register (info, NULL);
                }
                cache [sig->param_count] = start;
                mono_mini_arch_unlock ();
@@ -6004,6 +6010,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                mono_stats.imt_thunks_size += code - start;
        g_assert (code - start <= size);
        mono_arch_flush_icache (start, size);
+
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
index b2a08666096f48f91f8b6b5fa65898484be9caaa..4ff795aeb6cb9fb6d7bb3731a1238b0e698b2cec 100644 (file)
@@ -1076,10 +1076,7 @@ MINI_OP(OP_GC_PARAM_SLOT_LIVENESS_DEF, "gc_param_slot_liveness_def", NONE, NONE,
 MINI_OP(OP_GENERIC_CLASS_INIT, "generic_class_init", NONE, IREG, NONE)
 
 /* Arch specific opcodes */
-/* #if defined(__native_client_codegen__) || defined(__native_client__) */
-/* We have to define these in terms of the TARGET defines, not NaCl defines */
-/* because genmdesc.pl doesn't have multiple defines per platform.          */
-#if defined(TARGET_AMD64) || defined(TARGET_X86)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)
 MINI_OP(OP_GC_SAFE_POINT,     "gc_safe_point", NONE, IREG, NONE)
 #endif
 
index 5bc983ae8cd6582787768fb692e4682291758291..fe5cc782f833f26e4d965be3e4667654fc703f5d 100644 (file)
@@ -96,6 +96,12 @@ mono_runtime_install_handlers (void)
 }
 #endif
 
+void
+mono_runtime_posix_install_handlers(void)
+{
+
+}
+
 void
 mono_runtime_shutdown_handlers (void)
 {
@@ -205,7 +211,7 @@ MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler)
        MONO_SIG_HANDLER_GET_CONTEXT;
 
        if (mono_thread_internal_current ())
-               ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
+               ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
        if (!ji) {
         if (mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
                        return;
index 976a7f2a518c25e2e6a5db63c7b049f6c216f24b..16d3eaf28ebb9fb5546e75f73733e5888a368a18 100644 (file)
@@ -380,7 +380,7 @@ mono_ppc_is_direct_call_sequence (guint32 *code)
 #define MAX_ARCH_DELEGATE_PARAMS 7
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len, gboolean aot)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count, gboolean aot)
 {
        guint8 *code, *start;
 
@@ -430,8 +430,13 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
                mono_arch_flush_icache (start, size);
        }
 
-       if (code_len)
-               *code_len = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+               g_free (name);
+       }
 
        return start;
 }
@@ -440,19 +445,15 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0, TRUE);
+       res = g_slist_prepend (res, info);
 
-       for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+               get_delegate_invoke_impl (&info, FALSE, i, TRUE);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -473,11 +474,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                if (cached)
                        return cached;
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL, FALSE);
-
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0, FALSE);
+                       mono_tramp_info_register (info, NULL);
+               }
                mono_memory_barrier ();
 
                cached = start;
@@ -501,7 +504,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL, FALSE);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count, FALSE);
+                       mono_tramp_info_register (info, NULL);
                }
 
                mono_memory_barrier ();
@@ -1091,8 +1096,10 @@ get_call_info (MonoMethodSignature *sig)
                                        cinfo->args [n].reg = fr;
                                        fr ++;
                                        FP_ALSO_IN_REG (gr ++);
+#if !defined(__mono_ppc64__)
                                        if (size == 8)
                                                FP_ALSO_IN_REG (gr ++);
+#endif
                                        ALWAYS_ON_STACK (stack_size += size);
                                } else {
                                        cinfo->args [n].offset = PPC_STACK_PARAM_OFFSET + stack_size;
@@ -1160,7 +1167,10 @@ get_call_info (MonoMethodSignature *sig)
                        cinfo->args [n].size = 4;
 
                        /* It was 7, now it is 8 in LinuxPPC */
-                       if (fr <= PPC_LAST_FPARG_REG) {
+                       if (fr <= PPC_LAST_FPARG_REG
+                       // For non-native vararg calls the parms must go in storage
+                                && !(!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG))
+                               ) {
                                cinfo->args [n].regtype = RegTypeFP;
                                cinfo->args [n].reg = fr;
                                fr ++;
@@ -1177,7 +1187,10 @@ get_call_info (MonoMethodSignature *sig)
                case MONO_TYPE_R8:
                        cinfo->args [n].size = 8;
                        /* It was 7, now it is 8 in LinuxPPC */
-                       if (fr <= PPC_LAST_FPARG_REG) {
+                       if (fr <= PPC_LAST_FPARG_REG
+                       // For non-native vararg calls the parms must go in storage
+                                && !(!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG))
+                                ) {
                                cinfo->args [n].regtype = RegTypeFP;
                                cinfo->args [n].reg = fr;
                                fr ++;
@@ -1349,7 +1362,7 @@ mono_arch_allocate_vars (MonoCompile *m)
                m->ret->inst_c0 = m->ret->dreg = ppc_r3;
        } else {
                /* FIXME: handle long values? */
-               switch (mini_get_underlying_type (m, sig->ret)->type) {
+               switch (mini_get_underlying_type (sig->ret)->type) {
                case MONO_TYPE_VOID:
                        break;
                case MONO_TYPE_R4:
@@ -4415,6 +4428,22 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        else
                                ppc_mr (code, ins->dreg, ins->sreg1);
                        break;
+#else
+               case OP_ICONV_TO_R4:
+               case OP_ICONV_TO_R8: {
+                       if (cpu_hw_caps & PPC_ISA_64) {
+                               ppc_srawi(code, ppc_r0, ins->sreg1, 31);
+                               ppc_stw (code, ppc_r0, -8, ppc_r1);
+                               ppc_stw (code, ins->sreg1, -4, ppc_r1);
+                               ppc_lfd (code, ins->dreg, -8, ppc_r1);
+                               ppc_fcfid (code, ins->dreg, ins->dreg);
+                               if (ins->opcode == OP_ICONV_TO_R4)
+                                       ppc_frsp (code, ins->dreg, ins->dreg);
+                               }
+                       break;
+               }
+#endif
+
                case OP_ATOMIC_ADD_I4:
                CASE_PPC64 (OP_ATOMIC_ADD_I8) {
                        int location = ins->inst_basereg;
@@ -4448,21 +4477,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ppc_mr (code, ins->dreg, ppc_r0);
                        break;
                }
-#else
-               case OP_ICONV_TO_R4:
-               case OP_ICONV_TO_R8: {
-                       if (cpu_hw_caps & PPC_ISA_64) {
-                               ppc_srawi(code, ppc_r0, ins->sreg1, 31);
-                               ppc_stw (code, ppc_r0, -8, ppc_r1);
-                               ppc_stw (code, ins->sreg1, -4, ppc_r1);
-                               ppc_lfd (code, ins->dreg, -8, ppc_r1);
-                               ppc_fcfid (code, ins->dreg, ins->dreg);
-                               if (ins->opcode == OP_ICONV_TO_R4)
-                                       ppc_frsp (code, ins->dreg, ins->dreg);
-                               }
-                       break;
-               }
-#endif
                case OP_ATOMIC_CAS_I4:
                CASE_PPC64 (OP_ATOMIC_CAS_I8) {
                        int location = ins->sreg1;
@@ -5742,6 +5756,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                mono_stats.imt_thunks_size += code - start;
        g_assert (code - start <= size);
        mono_arch_flush_icache (start, size);
+
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
index 0c611f251a54f7e70eb00d4d4671301c648dfb55..45e5dc3e60acc2d8147222b66a121de57e5a22b0 100644 (file)
@@ -139,8 +139,15 @@ typedef struct MonoCompileArch {
 /* Linux */
 #ifdef __mono_ppc64__
 #define PPC_RET_ADDR_OFFSET 16
-#define PPC_STACK_PARAM_OFFSET 48
-#define PPC_MINIMAL_STACK_SIZE 48
+ // Power LE abvi2
+ #if (_CALL_ELF == 2)
+  #define PPC_STACK_PARAM_OFFSET 32
+  #define PPC_MINIMAL_STACK_SIZE 32
+ #else
+  #define PPC_STACK_PARAM_OFFSET 48
+  #define PPC_MINIMAL_STACK_SIZE 48
+ #endif
+#define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
 #define PPC_MINIMAL_PARAM_AREA_SIZE 64
 #define PPC_LAST_FPARG_REG ppc_f13
 #define PPC_PASS_STRUCTS_BY_VALUE 1
index 27bc1fb5b2a59b661c9d3fd18dbe882b2a80717f..8b454087638bef15f630ffa4446e8e57391fc72f 100644 (file)
@@ -59,6 +59,7 @@
 #include <mono/utils/dtrace.h>
 #include <mono/utils/mono-signal-handler.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/checked-build.h>
 #include <mono/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -118,12 +119,14 @@ static void register_icalls (void);
 gboolean
 mono_running_on_valgrind (void)
 {
+#ifndef HOST_WIN32
        if (RUNNING_ON_VALGRIND){
 #ifdef VALGRIND_JIT_REGISTER_MAP
                valgrind_register = TRUE;
 #endif
                return TRUE;
        } else
+#endif
                return FALSE;
 }
 
@@ -155,7 +158,7 @@ get_method_from_ip (void *ip)
        if (!domain)
                domain = mono_get_root_domain ();
 
-       ji = mono_jit_info_table_find (domain, ip);
+       ji = mono_jit_info_table_find_internal (domain, ip, TRUE, TRUE);
        if (!ji) {
                user_data.ip = ip;
                user_data.method = NULL;
@@ -170,7 +173,11 @@ get_method_from_ip (void *ip)
                }
                else
                        return NULL;
+       } else if (ji->is_trampoline) {
+               res = g_strdup_printf ("<%p - %s trampoline>", ip, ((MonoTrampInfo*)ji->d.tramp_info)->name);
+               return res;
        }
+
        method = mono_method_full_name (jinfo_get_method (ji), TRUE);
        /* FIXME: unused ? */
        location = mono_debug_lookup_source_location (jinfo_get_method (ji), (guint32)((guint8*)ip - (guint8*)ji->code_start), domain);
@@ -286,7 +293,7 @@ gboolean mono_method_same_domain (MonoJitInfo *caller, MonoJitInfo *callee)
 {
        MonoMethod *cmethod;
 
-       if (!caller || !callee)
+       if (!caller || caller->is_trampoline || !callee || callee->is_trampoline)
                return FALSE;
 
        /*
@@ -460,14 +467,10 @@ mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJ
 void
 mono_tramp_info_free (MonoTrampInfo *info)
 {
-       GSList *l;
-
        g_free (info->name);
 
        // FIXME: ji
-       for (l = info->unwind_ops; l; l = l->next)
-               g_free (l->data);
-       g_slist_free (info->unwind_ops);
+       mono_free_unwind_info (info->unwind_ops);
        g_free (info);
 }
 
@@ -480,7 +483,8 @@ register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info)
        mono_jit_info_init (ji, NULL, info->code, info->code_size, 0, 0, 0);
        ji->d.tramp_info = info;
        ji->is_trampoline = TRUE;
-       // FIXME: Unwind info
+
+       ji->unwind_info = mono_cache_unwind_info (info->uw_info, info->uw_info_len);
 
        mono_jit_info_table_add (domain, ji);
 }
@@ -493,26 +497,38 @@ register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info)
  * Frees INFO.
  */
 void
-mono_tramp_info_register (MonoTrampInfo *info)
+mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
 {
        MonoTrampInfo *copy;
 
        if (!info)
                return;
 
+       if (!domain)
+               domain = mono_get_root_domain ();
+
        copy = g_new0 (MonoTrampInfo, 1);
        copy->code = info->code;
        copy->code_size = info->code_size;
        copy->name = g_strdup (info->name);
 
+       if (info->unwind_ops) {
+               copy->uw_info = mono_unwind_ops_encode (info->unwind_ops, &copy->uw_info_len);
+       } else {
+               /* Trampolines from aot have the unwind ops already encoded */
+               copy->uw_info = info->uw_info;
+               copy->uw_info_len = info->uw_info_len;
+       }
+
        mono_jit_lock ();
        tramp_infos = g_slist_prepend (tramp_infos, copy);
        mono_jit_unlock ();
 
        mono_save_trampoline_xdebug_info (info);
 
-       if (mono_get_root_domain ())
-               register_trampoline_jit_info (mono_get_root_domain (), copy);
+       /* Only register trampolines that have unwind infos */
+       if (mono_get_root_domain () && copy->uw_info)
+               register_trampoline_jit_info (domain, copy);
 
        if (mono_jit_map_is_enabled ())
                mono_emit_jit_tramp (info->code, info->code_size, info->name);
@@ -590,26 +606,12 @@ mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile)
        MonoDomain *domain = mono_get_root_domain ();
        gboolean check_exc = TRUE;
 
-       if (callinfo->wrapper) {
+       if (callinfo->wrapper)
                return callinfo->wrapper;
-       }
 
        if (callinfo->trampoline)
                return callinfo->trampoline;
 
-       /*
-        * We use the lock on the root domain instead of the JIT lock to protect
-        * callinfo->trampoline, since we do a lot of stuff inside the critical section.
-        */
-       mono_loader_lock (); /*FIXME mono_compile_method requires the loader lock, by large.*/
-       mono_domain_lock (domain);
-
-       if (callinfo->trampoline) {
-               mono_domain_unlock (domain);
-               mono_loader_unlock ();
-               return callinfo->trampoline;
-       }
-
        if (!strcmp (callinfo->name, "mono_thread_interruption_checkpoint"))
                /* This icall is used to check for exceptions, so don't check in the wrapper */
                check_exc = FALSE;
@@ -622,11 +624,12 @@ mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile)
                trampoline = mono_compile_method (wrapper);
        else
                trampoline = mono_create_ftnptr (domain, mono_create_jit_trampoline_in_domain (domain, wrapper));
-       mono_register_jit_icall_wrapper (callinfo, trampoline);
 
-       callinfo->trampoline = trampoline;
-
-       mono_domain_unlock (domain);
+       mono_loader_lock ();
+       if (!callinfo->trampoline) {
+               mono_register_jit_icall_wrapper (callinfo, trampoline);
+               callinfo->trampoline = trampoline;
+       }
        mono_loader_unlock ();
 
        return callinfo->trampoline;
@@ -653,7 +656,9 @@ mono_dynamic_code_hash_lookup (MonoDomain *domain, MonoMethod *method)
 static void
 register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, const char *symbol, gboolean no_throw)
 {
+#ifndef DISABLE_JIT
        mini_register_opcode_emulation (opcode, name, sigstr, func, symbol, no_throw);
+#endif
 }
 
 /*
@@ -1199,9 +1204,6 @@ mono_patch_info_hash (gconstpointer data)
        case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
        case MONO_PATCH_INFO_GC_NURSERY_START:
        case MONO_PATCH_INFO_JIT_TLS_ID:
-       case MONO_PATCH_INFO_MONITOR_ENTER:
-       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
-       case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_GOT_OFFSET:
        case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
                return (ji->type << 8);
@@ -1589,15 +1591,6 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                target = mono_create_rgctx_lazy_fetch_trampoline (slot);
                break;
        }
-       case MONO_PATCH_INFO_MONITOR_ENTER:
-               target = mono_create_monitor_enter_trampoline ();
-               break;
-       case MONO_PATCH_INFO_MONITOR_ENTER_V4:
-               target = mono_create_monitor_enter_v4_trampoline ();
-               break;
-       case MONO_PATCH_INFO_MONITOR_EXIT:
-               target = mono_create_monitor_exit_trampoline ();
-               break;
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
        case MONO_PATCH_INFO_SEQ_POINT_INFO:
                if (!run_cctors)
@@ -1969,6 +1962,8 @@ mono_jit_free_method (MonoDomain *domain, MonoMethod *method)
        mono_internal_hash_table_remove (&domain->jit_code_hash, method);
        mono_domain_jit_code_hash_unlock (domain);
        g_hash_table_remove (domain_jit_info (domain)->jump_trampoline_hash, method);
+
+       /* requires the domain lock - took above */
        mono_conc_hashtable_remove (domain_jit_info (domain)->runtime_invoke_hash, method);
 
        /* Remove jump targets in this method */
@@ -2252,7 +2247,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                if (!info->dyn_call_info)
                        info->runtime_invoke = mono_jit_compile_method (invoke);
 
+               mono_domain_lock (domain);
                info2 = mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info);
+               mono_domain_unlock (domain);
                if (info2) {
                        g_free (info);
                        info = info2;
@@ -2333,7 +2330,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
        MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
        MONO_SIG_HANDLER_GET_CONTEXT;
 
-       ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
+       ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
 
 #if defined(MONO_ARCH_HAVE_IS_INT_OVERFLOW)
        if (mono_arch_is_int_overflow (ctx, info))
@@ -2419,7 +2416,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
        }
 #endif
 
-       ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
+       ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
 
 #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
        if (mono_handle_soft_stack_ovf (jit_tls, ji, ctx, info, (guint8*)info->si_addr))
@@ -2599,8 +2596,10 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met
        /* FIXME Support more cases */
        if (mono_aot_only) {
                char tramp_name [256];
+               const char *imt = load_imt_reg ? "_imt" : "";
+               int ind = (load_imt_reg ? (-offset) : offset) / SIZEOF_VOID_P;
 
-               sprintf (tramp_name, "delegate_virtual_invoke%s_%d", load_imt_reg ? "_imt" : "", offset / SIZEOF_VOID_P);
+               sprintf (tramp_name, "delegate_virtual_invoke%s_%d", imt, ind);
                cache [idx] = mono_aot_get_trampoline (tramp_name);
                g_assert (cache [idx]);
        } else {
@@ -2786,7 +2785,7 @@ mini_create_jit_domain_info (MonoDomain *domain)
        info->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
        info->delegate_trampoline_hash = g_hash_table_new (class_method_pair_hash, class_method_pair_equal);
        info->llvm_vcall_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
-       info->runtime_invoke_hash = mono_conc_hashtable_new_full (&domain->lock, mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free);
+       info->runtime_invoke_hash = mono_conc_hashtable_new_full (mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free);
        info->seq_points = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, mono_seq_point_info_free);
        info->arch_seq_points = g_hash_table_new (mono_aligned_addr_hash, NULL);
        info->jump_target_hash = g_hash_table_new (NULL, NULL);
@@ -2912,6 +2911,8 @@ mini_init (const char *filename, const char *runtime_version)
 
        MONO_VES_INIT_BEGIN ();
 
+       CHECKED_MONO_INIT ();
+
 #if defined(__linux__) && !defined(__native_client__)
        if (access ("/proc/self/maps", F_OK) != 0) {
                g_print ("Mono requires /proc to be mounted.\n");
@@ -2965,6 +2966,7 @@ mini_init (const char *filename, const char *runtime_version)
        ticallbacks.setup_async_callback = mono_setup_async_callback;
        ticallbacks.thread_state_init_from_sigctx = mono_thread_state_init_from_sigctx;
        ticallbacks.thread_state_init_from_handle = mono_thread_state_init_from_handle;
+       ticallbacks.thread_state_init = mono_thread_state_init;
 
        mono_counters_init ();
 
@@ -3133,8 +3135,6 @@ register_icalls (void)
                                ves_icall_get_frame_info);
        mono_add_internal_call ("System.Diagnostics.StackTrace::get_trace",
                                ves_icall_get_trace);
-       mono_add_internal_call ("System.Exception::get_trace",
-                               ves_icall_System_Exception_get_trace);
        mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers",
                                mono_runtime_install_handlers);
 
@@ -3481,8 +3481,6 @@ mini_cleanup (MonoDomain *domain)
 
        mono_mutex_destroy (&jit_mutex);
 
-       mono_mutex_destroy (&mono_delegate_section);
-
        mono_code_manager_cleanup ();
 
 #ifdef USE_JUMP_TABLES
@@ -3594,6 +3592,17 @@ void mono_precompile_assemblies ()
        g_hash_table_destroy (assemblies);
 }
 
+/*
+ * Used by LLVM.
+ * Have to export this for AOT.
+ */
+void
+mono_personality (void)
+{
+       /* Not used */
+       g_assert_not_reached ();
+}
+
 #ifdef USE_JUMP_TABLES
 #define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
 
index 0b482454c2cf3df4b5cc8d780195e836e1fdeee1..657ee174d981764341c44fed9e5612b6304fc8df 100644 (file)
@@ -5708,7 +5708,7 @@ mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *cl
 /*------------------------------------------------------------------*/
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len, gboolean aot)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count, gboolean aot)
 {
        guint8 *code, *start;
 
@@ -5744,8 +5744,13 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
 
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
 
-       if (code_len)
-               *code_len = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+               g_free (name);
+       }
 
        return start;
 }
@@ -5764,19 +5769,15 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0, TRUE);
+       res = g_slist_prepend (res, info);
 
-       for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+               get_delegate_invoke_impl (&info, FALSE, i, TRUE);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -5807,10 +5808,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                if (cached)
                        return cached;
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL, FALSE);
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0, FALSE);
+                       mono_tramp_info_register (info, NULL);
+               }
 
                mono_memory_barrier ();
 
@@ -5835,7 +5839,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL, FALSE);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count, FALSE);
+                       mono_tramp_info_register (info, NULL);
                }
 
                mono_memory_barrier ();
@@ -6028,6 +6034,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
 
        g_assert (code - start <= size);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return (start);
 }
 
index 740ae80e1e35b25acd425a024e54e1ff0dca1199..1de03e2fd2af0df5e8b3b4cc2ac0665ab7b6c622 100644 (file)
@@ -63,8 +63,6 @@ typedef struct
 #define MONO_ARCH_HAVE_INVALIDATE_METHOD               1
 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT           1
 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK            1
-#define MONO_ARCH_MONITOR_OBJECT_REG                   s390_r2
-#define MONO_ARCH_LOCK_TAKEN_REG                       s390_r1
 
 #define S390_STACK_ALIGNMENT            8
 #define S390_FIRST_ARG_REG             s390_r2
index f5c0f5e89d10e3863b6f3a1112f117460673d036..5aa8d082007347d3e00681ef66511cd42582b899 100644 (file)
@@ -2352,6 +2352,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 
        mono_stats.imt_thunks_size += (code - start) * 4;
        g_assert (code - start <= size);
+
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
index 72e8604c2acb36d3ec59a353ab31a9ccfc6fefa0..d4af8df57a08e4065f746f834cfc369e426a6a9c 100644 (file)
@@ -340,7 +340,7 @@ mini_add_method_trampoline (MonoMethod *m, gpointer compiled_method, gboolean ad
                }
        }
 
-       if (ji)
+       if (ji && !ji->is_trampoline)
                jmethod = jinfo_get_method (ji);
        if (callee_gsharedvt && mini_is_gsharedvt_variable_signature (mono_method_signature (jmethod))) {
                MonoMethodSignature *sig, *gsig;
@@ -896,29 +896,6 @@ mono_rgctx_lazy_fetch_trampoline (mgreg_t *regs, guint8 *code, gpointer data, gu
                return mono_class_fill_runtime_generic_context (arg, index);
 }
 
-void
-mono_monitor_enter_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-       mono_monitor_enter (obj);
-}
-
-void
-mono_monitor_enter_v4_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
-       char *lock_taken = (char*)regs [MONO_ARCH_MONITOR_LOCK_TAKEN_REG];
-       mono_monitor_enter_v4 (obj, lock_taken);
-#else
-       g_assert_not_reached ();
-#endif
-}
-
-void
-mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-       mono_monitor_exit (obj);
-}
-
 /*
  * Precompute data to speed up mono_delegate_trampoline ().
  * METHOD might be NULL.
@@ -1025,7 +1002,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
                                }
                        }
                }
-       } else {
+       // If "delegate->method_ptr" is null mono_get_addr_from_ftnptr will fail if
+       // ftnptrs are being used.  "method" would end up null on archtitectures without
+       // ftnptrs so we can just skip this.
+       } else if (delegate->method_ptr) {
                ji = mono_jit_info_table_find (domain, mono_get_addr_from_ftnptr (delegate->method_ptr));
                if (ji)
                        method = jinfo_get_method (ji);
@@ -1171,7 +1151,7 @@ mono_create_handler_block_trampoline (void)
                gpointer tmp;
 
                tmp = mono_arch_create_handler_block_trampoline (&info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                mono_memory_barrier ();
                code = tmp;
        }
@@ -1210,12 +1190,6 @@ mono_get_trampoline_func (MonoTrampolineType tramp_type)
        case MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING:
                return mono_generic_virtual_remoting_trampoline;
 #endif
-       case MONO_TRAMPOLINE_MONITOR_ENTER:
-               return mono_monitor_enter_trampoline;
-       case MONO_TRAMPOLINE_MONITOR_ENTER_V4:
-               return mono_monitor_enter_v4_trampoline;
-       case MONO_TRAMPOLINE_MONITOR_EXIT:
-               return mono_monitor_exit_trampoline;
        case MONO_TRAMPOLINE_VCALL:
                return mono_vcall_trampoline;
 #ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
@@ -1235,7 +1209,7 @@ create_trampoline_code (MonoTrampolineType tramp_type)
        guchar *code;
 
        code = mono_arch_create_generic_trampoline (tramp_type, &info, FALSE);
-       mono_tramp_info_register (info);
+       mono_tramp_info_register (info, NULL);
 
        return code;
 }
@@ -1260,9 +1234,6 @@ mono_trampolines_init (void)
 #ifndef DISABLE_REMOTING
        mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
 #endif
-       mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER);
-       mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER_V4] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER_V4);
-       mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_EXIT] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
        mono_trampoline_code [MONO_TRAMPOLINE_VCALL] = create_trampoline_code (MONO_TRAMPOLINE_VCALL);
 #ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
        mono_trampoline_code [MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD] = create_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
@@ -1479,7 +1450,7 @@ mono_create_rgctx_lazy_fetch_trampoline (guint32 offset)
                ptr = mono_aot_get_lazy_fetch_trampoline (offset);
        } else {
                tramp = mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, FALSE);
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
                ptr = mono_create_ftnptr (mono_get_root_domain (), tramp);
        }
 
@@ -1502,95 +1473,6 @@ mono_create_rgctx_lazy_fetch_trampoline (guint32 offset)
 
        return ptr;
 }
-
-gpointer
-mono_create_monitor_enter_trampoline (void)
-{
-       static gpointer code;
-
-       if (mono_aot_only) {
-               if (!code)
-                       code = mono_aot_get_trampoline ("monitor_enter_trampoline");
-               return code;
-       }
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-       mono_trampolines_lock ();
-
-       if (!code) {
-               MonoTrampInfo *info;
-
-               code = mono_arch_create_monitor_enter_trampoline (&info, FALSE, FALSE);
-               mono_tramp_info_register (info);
-       }
-
-       mono_trampolines_unlock ();
-#else
-       code = NULL;
-       g_assert_not_reached ();
-#endif
-
-       return code;
-}
-
-gpointer
-mono_create_monitor_enter_v4_trampoline (void)
-{
-       static gpointer code;
-
-       if (mono_aot_only) {
-               if (!code)
-                       code = mono_aot_get_trampoline ("monitor_enter_v4_trampoline");
-               return code;
-       }
-
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG) && defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
-       mono_trampolines_lock ();
-
-       if (!code) {
-               MonoTrampInfo *info;
-
-               code = mono_arch_create_monitor_enter_trampoline (&info, TRUE, FALSE);
-               mono_tramp_info_register (info);
-       }
-
-       mono_trampolines_unlock ();
-#else
-       code = NULL;
-       g_assert_not_reached ();
-#endif
-
-       return code;
-}
-
-gpointer
-mono_create_monitor_exit_trampoline (void)
-{
-       static gpointer code;
-
-       if (mono_aot_only) {
-               if (!code)
-                       code = mono_aot_get_trampoline ("monitor_exit_trampoline");
-               return code;
-       }
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-       mono_trampolines_lock ();
-
-       if (!code) {
-               MonoTrampInfo *info;
-
-               code = mono_arch_create_monitor_exit_trampoline (&info, FALSE);
-               mono_tramp_info_register (info);
-       }
-
-       mono_trampolines_unlock ();
-#else
-       code = NULL;
-       g_assert_not_reached ();
-#endif
-       return code;
-}
  
 #ifdef MONO_ARCH_LLVM_SUPPORTED
 /*
@@ -1641,9 +1523,6 @@ static const char*tramp_names [MONO_TRAMPOLINE_NUM] = {
        "delegate",
        "restore_stack_prot",
        "generic_virtual_remoting",
-       "monitor_enter",
-       "monitor_enter_v4",
-       "monitor_exit",
        "vcall",
        "handler_block_guard"
 };
@@ -1705,7 +1584,7 @@ mini_get_single_step_trampoline (void)
 #ifdef MONO_ARCH_HAVE_SDB_TRAMPOLINES
                        MonoTrampInfo *info;
                        tramp = mono_arch_create_sdb_trampoline (TRUE, &info, FALSE);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
 #else
                        tramp = NULL;
                        g_assert_not_reached ();
@@ -1737,7 +1616,7 @@ mini_get_breakpoint_trampoline (void)
 #ifdef MONO_ARCH_HAVE_SDB_TRAMPOLINES
                        MonoTrampInfo *info;
                        tramp = mono_arch_create_sdb_trampoline (FALSE, &info, FALSE);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
 #else
                        tramp = NULL;
                        g_assert_not_reached ();
index 657cc7708733634fb42208d8378dda25d6af5e53..ab690bf480797779f46c823999285c9b438a520c 100644 (file)
@@ -114,6 +114,8 @@ typedef struct {
 #define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (reg), 0)); } while (0)
 #define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (reg), (offset))); } while (0)
 
+#define mono_free_unwind_info(op_list) do { GSList *l; for (l = op_list; l; l = l->next) g_free (l->data); g_slist_free (op_list); op_list = NULL; } while (0)
+
 /* Pointer Encoding in the .eh_frame */
 enum {
        DW_EH_PE_absptr = 0x00,
@@ -144,6 +146,9 @@ mono_unwind_get_dwarf_data_align (void);
 int
 mono_unwind_get_dwarf_pc_reg (void);
 
+guint8*
+mono_unwind_ops_encode_full (GSList *unwind_ops, guint32 *out_len, gboolean enable_extensions);
+
 guint8*
 mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len);
 
index 4242c2b83e3a11eb4882ee94629da983c5233efa..07dcd6f9c46d82204cb54286a3847cc74938bb19 100644 (file)
@@ -45,6 +45,12 @@ static gboolean optimize_for_xen = TRUE;
 #endif
 #endif
 
+/* The single step trampoline */
+static gpointer ss_trampoline;
+
+/* The breakpoint trampoline */
+static gpointer bp_trampoline;
+
 /* This mutex protects architecture specific caches */
 #define mono_mini_arch_lock() mono_mutex_lock (&mini_arch_mutex)
 #define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
@@ -63,8 +69,7 @@ static mono_mutex_t mini_arch_mutex;
 
 #define X86_IS_CALLEE_SAVED_REG(reg) (((reg) == X86_EBX) || ((reg) == X86_EDI) || ((reg) == X86_ESI))
 
-MonoBreakpointInfo
-mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+#define OP_SEQ_POINT_BP_OFFSET 7
 
 static guint8*
 emit_load_aotconst (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji, int dreg, int tramp_type, gconstpointer target);
@@ -102,15 +107,6 @@ mono_arch_nacl_skip_nops (guint8 *code)
 
 #endif /* __native_client_codegen__ */
 
-/*
- * The code generated for sequence points reads from this location, which is
- * made read-only when single stepping is enabled.
- */
-static gpointer ss_trigger_page;
-
-/* Enabled breakpoints read from this trigger page */
-static gpointer bp_trigger_page;
-
 const char*
 mono_arch_regname (int reg)
 {
@@ -760,9 +756,8 @@ mono_arch_init (void)
 {
        mono_mutex_init_recursive (&mini_arch_mutex);
 
-       ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
-       bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
-       mono_mprotect (bp_trigger_page, mono_pagesize (), 0);
+       if (!mono_aot_only)
+               bp_trampoline = mini_get_breakpoint_trampoline ();
 
        mono_aot_register_jit_icall ("mono_x86_throw_exception", mono_x86_throw_exception);
        mono_aot_register_jit_icall ("mono_x86_throw_corlib_exception", mono_x86_throw_corlib_exception);
@@ -777,10 +772,6 @@ mono_arch_init (void)
 void
 mono_arch_cleanup (void)
 {
-       if (ss_trigger_page)
-               mono_vfree (ss_trigger_page, mono_pagesize ());
-       if (bp_trigger_page)
-               mono_vfree (bp_trigger_page, mono_pagesize ());
        mono_mutex_destroy (&mini_arch_mutex);
 }
 
@@ -1217,6 +1208,18 @@ mono_arch_create_vars (MonoCompile *cfg)
                cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
        }
 
+       if (cfg->gen_sdb_seq_points) {
+               MonoInst *ins;
+
+               ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+               ins->flags |= MONO_INST_VOLATILE;
+               cfg->arch.ss_tramp_var = ins;
+
+               ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+               ins->flags |= MONO_INST_VOLATILE;
+               cfg->arch.bp_tramp_var = ins;
+       }
+
        if (cfg->method->save_lmf) {
                cfg->create_lmf_var = TRUE;
                cfg->lmf_ir = TRUE;
@@ -2773,22 +2776,53 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (cfg->compile_aot)
                                NOT_IMPLEMENTED;
 
+                       /* Have to use ecx as a temp reg since this can occur after OP_SETRET */
+
                        /* 
                         * Read from the single stepping trigger page. This will cause a
                         * SIGSEGV when single stepping is enabled.
                         * We do this _before_ the breakpoint, so single stepping after
                         * a breakpoint is hit will step to the next IL offset.
                         */
-                       if (ins->flags & MONO_INST_SINGLE_STEP_LOC)
-                               x86_alu_reg_mem (code, X86_CMP, X86_EAX, (guint32)ss_trigger_page);
+                       if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
+                               MonoInst *var = cfg->arch.ss_tramp_var;
+                               guint8 *br [1];
+
+                               g_assert (var);
+                               g_assert (var->opcode == OP_REGOFFSET);
+                               /* Load ss_tramp_var */
+                               /* This is equal to &ss_trampoline */
+                               x86_mov_reg_membase (code, X86_ECX, var->inst_basereg, var->inst_offset, sizeof (mgreg_t));
+                               x86_alu_membase_imm (code, X86_CMP, X86_ECX, 0, 0);
+                               br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+                               x86_call_membase (code, X86_ECX, 0);
+                               x86_patch (br [0], code);
+                       }
+
+                       /*
+                        * Many parts of sdb depend on the ip after the single step trampoline call to be equal to the seq point offset.
+                        * This means we have to put the loading of bp_tramp_var after the offset.
+                        */
 
                        mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
 
+                       MonoInst *var = cfg->arch.bp_tramp_var;
+
+                       g_assert (var);
+                       g_assert (var->opcode == OP_REGOFFSET);
+                       /* Load the address of the bp trampoline */
+                       /* This needs to be constant size */
+                       guint8 *start = code;
+                       x86_mov_reg_membase (code, X86_ECX, var->inst_basereg, var->inst_offset, 4);
+                       if (code < start + OP_SEQ_POINT_BP_OFFSET) {
+                               int size = start + OP_SEQ_POINT_BP_OFFSET - code;
+                               x86_padding (code, size);
+                       }
                        /* 
                         * A placeholder for a possible breakpoint inserted by
                         * mono_arch_set_breakpoint ().
                         */
-                       for (i = 0; i < 6; ++i)
+                       for (i = 0; i < 2; ++i)
                                x86_nop (code);
                        /*
                         * Add an additional nop so skipping the bp doesn't cause the ip to point
@@ -5402,6 +5436,28 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
                code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, code, TRUE);
 
+       {
+               MonoInst *ins;
+
+               if (cfg->arch.ss_tramp_var) {
+                       /* Initialize ss_tramp_var */
+                       ins = cfg->arch.ss_tramp_var;
+                       g_assert (ins->opcode == OP_REGOFFSET);
+
+                       g_assert (!cfg->compile_aot);
+                       x86_mov_membase_imm (code, ins->inst_basereg, ins->inst_offset, (guint32)&ss_trampoline, 4);
+               }
+
+               if (cfg->arch.bp_tramp_var) {
+                       /* Initialize bp_tramp_var */
+                       ins = cfg->arch.bp_tramp_var;
+                       g_assert (ins->opcode == OP_REGOFFSET);
+
+                       g_assert (!cfg->compile_aot);
+                       x86_mov_membase_imm (code, ins->inst_basereg, ins->inst_offset, (guint32)&bp_trampoline, 4);
+               }
+       }
+
        /* load arguments allocated to register from the stack */
        sig = mono_method_signature (method);
        pos = 0;
@@ -5762,6 +5818,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        int i;
        int size = 0;
        guint8 *code, *start;
+       GSList *unwind_ops;
 
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
@@ -5798,6 +5855,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                code = mono_domain_code_reserve (domain, size);
 #endif
        start = code;
+
+       unwind_ops = mono_arch_get_cie_program ();
+
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
                item->code_target = code;
@@ -5884,6 +5944,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        nacl_domain_code_validate (domain, &start, size, &code);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -6075,10 +6137,13 @@ mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code)
 #define MAX_ARCH_DELEGATE_PARAMS 10
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count)
 {
        guint8 *code, *start;
        int code_reserve = 64;
+       GSList *unwind_ops;
+
+       unwind_ops = mono_arch_get_cie_program ();
 
        /*
         * The stack contains:
@@ -6139,8 +6204,13 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
 
        nacl_global_codeman_validate (&start, code_reserve, &code);
 
-       if (code_len)
-               *code_len = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+               g_free (name);
+       }
 
        if (mono_jit_map_is_enabled ()) {
                char *buff;
@@ -6160,10 +6230,15 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
 #define MAX_VIRTUAL_DELEGATE_OFFSET 32
 
 static gpointer
-get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *code_size)
+get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, int offset)
 {
        guint8 *code, *start;
        int size = 24;
+       char *tramp_name;
+       GSList *unwind_ops;
+
+       if (offset / (int)sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
+               return NULL;
 
        /*
         * The stack contains:
@@ -6172,6 +6247,8 @@ get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *co
         */
        start = code = mono_global_codeman_reserve (size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        /* Replace the this argument with the target */
        x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4);
        x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 4);
@@ -6187,8 +6264,13 @@ get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *co
        x86_jump_membase (code, X86_EAX, offset);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
 
-       if (code_size)
-               *code_size = code - start;
+       if (load_imt_reg)
+               tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
+       else
+               tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+       *info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
+       g_free (tramp_name);
+
 
        return start;
 }
@@ -6197,31 +6279,23 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0);
+       res = g_slist_prepend (res, info);
 
-       for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+               get_delegate_invoke_impl (&info, FALSE, i);
+               res = g_slist_prepend (res, info);
        }
 
-       for (i = 0; i < MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
-               code = get_delegate_virtual_invoke_impl (TRUE, i * SIZEOF_VOID_P, &code_len);
-               tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+               get_delegate_virtual_invoke_impl (&info, TRUE, - i * SIZEOF_VOID_P);
+               res = g_slist_prepend (res, info);
 
-               code = get_delegate_virtual_invoke_impl (FALSE, i * SIZEOF_VOID_P, &code_len);
-               tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+               get_delegate_virtual_invoke_impl (&info, FALSE, i * SIZEOF_VOID_P);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -6250,10 +6324,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                if (cached)
                        return cached;
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL);
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0);
+                       mono_tramp_info_register (info, NULL);
+               }
 
                mono_memory_barrier ();
 
@@ -6275,7 +6352,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+                       mono_tramp_info_register (info, NULL);
                }
 
                mono_memory_barrier ();
@@ -6289,7 +6368,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 gpointer
 mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
 {
-       return get_delegate_virtual_invoke_impl (load_imt_reg, offset, NULL);
+       MonoTrampInfo *info;
+       gpointer code;
+
+       code = get_delegate_virtual_invoke_impl (&info, load_imt_reg, offset);
+       if (code)
+               mono_tramp_info_register (info, NULL);
+       return code;
 }
 
 mgreg_t
@@ -6623,15 +6708,10 @@ mono_arch_get_trampolines (gboolean aot)
 void
 mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip)
 {
-       guint8 *code = ip;
+       guint8 *code = ip + OP_SEQ_POINT_BP_OFFSET;
 
-       /* 
-        * In production, we will use int3 (has to fix the size in the md 
-        * file). But that could confuse gdb, so during development, we emit a SIGSEGV
-        * instead.
-        */
        g_assert (code [0] == 0x90);
-       x86_alu_reg_mem (code, X86_CMP, X86_EAX, (guint32)bp_trigger_page);
+       x86_call_membase (code, X86_ECX, 0);
 }
 
 /*
@@ -6642,10 +6722,10 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip)
 void
 mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip)
 {
-       guint8 *code = ip;
+       guint8 *code = ip + OP_SEQ_POINT_BP_OFFSET;
        int i;
 
-       for (i = 0; i < 6; ++i)
+       for (i = 0; i < 2; ++i)
                x86_nop (code);
 }
        
@@ -6657,7 +6737,7 @@ mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip)
 void
 mono_arch_start_single_stepping (void)
 {
-       mono_mprotect (ss_trigger_page, mono_pagesize (), 0);
+       ss_trampoline = mini_get_single_step_trampoline ();
 }
        
 /*
@@ -6668,7 +6748,7 @@ mono_arch_start_single_stepping (void)
 void
 mono_arch_stop_single_stepping (void)
 {
-       mono_mprotect (ss_trigger_page, mono_pagesize (), MONO_MMAP_READ);
+       ss_trampoline = NULL;
 }
 
 /*
@@ -6680,43 +6760,18 @@ mono_arch_stop_single_stepping (void)
 gboolean
 mono_arch_is_single_step_event (void *info, void *sigctx)
 {
-#ifdef TARGET_WIN32
-       EXCEPTION_RECORD* einfo = ((EXCEPTION_POINTERS*)info)->ExceptionRecord; /* Sometimes the address is off by 4 */
-
-       if (((gpointer)einfo->ExceptionInformation[1] >= ss_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)ss_trigger_page + 128))
-               return TRUE;
-       else
-               return FALSE;
-#else
-       siginfo_t* sinfo = (siginfo_t*) info;
-       /* Sometimes the address is off by 4 */
-       if (sinfo->si_signo == DBG_SIGNAL && (sinfo->si_addr >= ss_trigger_page && (guint8*)sinfo->si_addr <= (guint8*)ss_trigger_page + 128))
-               return TRUE;
-       else
-               return FALSE;
-#endif
+       /* We use soft breakpoints */
+       return FALSE;
 }
 
 gboolean
 mono_arch_is_breakpoint_event (void *info, void *sigctx)
 {
-#ifdef TARGET_WIN32
-       EXCEPTION_RECORD* einfo = ((EXCEPTION_POINTERS*)info)->ExceptionRecord; /* Sometimes the address is off by 4 */
-       if (((gpointer)einfo->ExceptionInformation[1] >= bp_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)bp_trigger_page + 128))
-               return TRUE;
-       else
-               return FALSE;
-#else
-       siginfo_t* sinfo = (siginfo_t*)info;
-       /* Sometimes the address is off by 4 */
-       if (sinfo->si_signo == DBG_SIGNAL && (sinfo->si_addr >= bp_trigger_page && (guint8*)sinfo->si_addr <= (guint8*)bp_trigger_page + 128))
-               return TRUE;
-       else
-               return FALSE;
-#endif
+       /* We use soft breakpoints */
+       return FALSE;
 }
 
-#define BREAKPOINT_SIZE 6
+#define BREAKPOINT_SIZE 2
 
 /*
  * mono_arch_skip_breakpoint:
@@ -6726,7 +6781,7 @@ mono_arch_is_breakpoint_event (void *info, void *sigctx)
 void
 mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji)
 {
-       MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + BREAKPOINT_SIZE);
+       g_assert_not_reached ();
 }
 
 /*
@@ -6737,7 +6792,7 @@ mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji)
 void
 mono_arch_skip_single_step (MonoContext *ctx)
 {
-       MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 6);
+       g_assert_not_reached ();
 }
 
 /*
index 149cbd1198f99408ec2ba91b878e367fdccd3783..0547b2c807eaf15c14fb52004f094f87c1073965 100644 (file)
@@ -165,6 +165,8 @@ typedef struct {
        gboolean need_stack_frame_inited;
        gboolean need_stack_frame;
        int sp_fp_offset, param_area_size;
+       gpointer ss_tramp_var;
+       gpointer bp_tramp_var;
 } MonoCompileArch;
 
 #define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->eax = (gsize)exc; } while (0)
@@ -214,10 +216,6 @@ typedef struct {
 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
 #define MONO_ARCH_HAVE_LIVERANGE_OPS 1
 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
-#if defined(__linux__) || defined (__APPLE__)
-#define MONO_ARCH_MONITOR_OBJECT_REG X86_EAX
-#define MONO_ARCH_MONITOR_LOCK_TAKEN_REG X86_EDX
-#endif
 #if !defined(__native_client_codegen__)
 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
 #endif
@@ -239,9 +237,7 @@ typedef struct {
 #define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1
 #define MONO_ARCH_LLVM_SUPPORTED 1
 
-#if defined(MONO_ARCH_USE_SIGACTION) || defined(TARGET_WIN32)
 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
-#endif
 
 #define MONO_ARCH_HAVE_EXCEPTIONS_INIT 1
 #define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1
@@ -256,6 +252,7 @@ typedef struct {
 #define MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET 1
 #define MONO_ARCH_HAVE_TLS_GET_REG 1
 #define MONO_ARCH_HAVE_DUMMY_INIT 1
+#define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
 #define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
 
 /* Used for optimization, not complete */
@@ -271,13 +268,6 @@ typedef struct {
                        MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \
        } while (0)
 
-typedef struct {
-       guint8 *address;
-       guint8 saved_byte;
-} MonoBreakpointInfo;
-
-extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
 /* Return value marshalling for calls between gsharedvt and normal code */
 typedef enum {
        GSHAREDVT_RET_NONE = 0,
index fd7d7c852be4a7545a5c22dfbe9c002f65a03939..607c627462d74ae7c6b9b7ad68963a47076726ef 100644 (file)
@@ -85,6 +85,8 @@ gboolean mono_using_xdebug;
 #define mono_jit_unlock() mono_mutex_unlock (&jit_mutex)
 static mono_mutex_t jit_mutex;
 
+#ifndef DISABLE_JIT
+
 gpointer
 mono_realloc_native_code (MonoCompile *cfg)
 {
@@ -196,6 +198,103 @@ void mono_nacl_fix_patches(const guint8 *code, MonoJumpInfo *ji)
 }
 #endif  /* __native_client_codegen__ */
 
+#ifdef USE_JUMP_TABLES
+
+#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
+
+typedef struct MonoJumpTableChunk {
+       guint32 total;
+       guint32 active;
+       struct MonoJumpTableChunk *previous;
+       /* gpointer entries[total]; */
+} MonoJumpTableChunk;
+
+static MonoJumpTableChunk* g_jumptable;
+#define mono_jumptable_lock() mono_mutex_lock (&jumptable_mutex)
+#define mono_jumptable_unlock() mono_mutex_unlock (&jumptable_mutex)
+static mono_mutex_t jumptable_mutex;
+
+static  MonoJumpTableChunk*
+mono_create_jumptable_chunk (guint32 max_entries)
+{
+       guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
+       MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
+       chunk->total = max_entries;
+       return chunk;
+}
+
+void
+mono_jumptable_init (void)
+{
+       if (g_jumptable == NULL) {
+               mono_mutex_init_recursive (&jumptable_mutex);
+               g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
+       }
+}
+
+gpointer*
+mono_jumptable_add_entry (void)
+{
+       return mono_jumptable_add_entries (1);
+}
+
+gpointer*
+mono_jumptable_add_entries (guint32 entries)
+{
+       guint32 index;
+       gpointer *result;
+
+       mono_jumptable_init ();
+       mono_jumptable_lock ();
+       index = g_jumptable->active;
+       if (index + entries >= g_jumptable->total) {
+               /*
+                * Grow jumptable, by adding one more chunk.
+                * We cannot realloc jumptable, as there could be pointers
+                * to existing jump table entries in the code, so instead
+                * we just add one more chunk.
+                */
+               guint32 max_entries = entries;
+               MonoJumpTableChunk *new_chunk;
+
+               if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
+                       max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
+               new_chunk = mono_create_jumptable_chunk (max_entries);
+               /* Link old jumptable, so that we could free it up later. */
+               new_chunk->previous = g_jumptable;
+               g_jumptable = new_chunk;
+               index = 0;
+       }
+       g_jumptable->active = index + entries;
+       result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
+       mono_jumptable_unlock();
+
+       return result;
+}
+
+void
+mono_jumptable_cleanup (void)
+{
+       if (g_jumptable) {
+               MonoJumpTableChunk *current = g_jumptable, *prev;
+               while (current != NULL) {
+                       prev = current->previous;
+                       g_free (current);
+                       current = prev;
+               }
+               g_jumptable = NULL;
+               mono_mutex_destroy (&jumptable_mutex);
+       }
+}
+
+gpointer*
+mono_jumptable_get_entry (guint8 *code_ptr)
+{
+       return mono_arch_jumptable_entry_from_code (code_ptr);
+}
+
+#endif /* USE_JUMP_TABLES */
+
 typedef struct {
        MonoExceptionClause *clause;
        MonoBasicBlock *basic_block;
@@ -532,19 +631,6 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type)
        return -1;
 }
 
-static guint
-mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
-{
-       type = mini_get_underlying_type (type);
-       if (cfg->gshared && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
-               g_assert (mini_type_var_is_vt (type));
-               return CEE_LDOBJ;
-       }
-       return mono_type_to_ldind (type);
-}
-
-#ifndef DISABLE_JIT
-
 guint
 mini_type_to_stind (MonoCompile* cfg, MonoType *type)
 {
@@ -688,8 +774,6 @@ mono_decompose_op_imm (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins)
        bb->max_vreg = MAX (bb->max_vreg, cfg->next_vreg);
 }
 
-#endif
-
 static void
 set_vreg_to_inst (MonoCompile *cfg, int vreg, MonoInst *inst)
 {
@@ -709,16 +793,6 @@ set_vreg_to_inst (MonoCompile *cfg, int vreg, MonoInst *inst)
 #define mono_type_is_long(type) (!(type)->byref && ((mono_type_get_underlying_type (type)->type == MONO_TYPE_I8) || (mono_type_get_underlying_type (type)->type == MONO_TYPE_U8)))
 #define mono_type_is_float(type) (!(type)->byref && (((type)->type == MONO_TYPE_R8) || ((type)->type == MONO_TYPE_R4)))
 
-#ifdef DISABLE_JIT
-
-MonoInst*
-mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
-{
-       return NULL;
-}
-
-#else
-
 MonoInst*
 mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, int vreg)
 {
@@ -848,19 +922,6 @@ mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
        return mono_compile_create_var_for_vreg (cfg, type, opcode, dreg);
 }
 
-/*
- * Transform a MonoInst into a load from the variable of index var_index.
- */
-void
-mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index)
-{
-       memset (dest, 0, sizeof (MonoInst));
-       dest->inst_i0 = cfg->varinfo [var_index];
-       dest->opcode = mini_type_to_ldind (cfg, dest->inst_i0->inst_vtype);
-       type_to_eval_stack_type (cfg, dest->inst_i0->inst_vtype, dest);
-       dest->klass = dest->inst_i0->klass;
-}
-
 MonoInst*
 mini_get_int_to_float_spill_area (MonoCompile *cfg)
 {
@@ -875,8 +936,6 @@ mini_get_int_to_float_spill_area (MonoCompile *cfg)
 #endif
 }
 
-#endif
-
 void
 mono_mark_vreg_as_ref (MonoCompile *cfg, int vreg)
 {
@@ -910,7 +969,8 @@ mono_mark_vreg_as_mp (MonoCompile *cfg, int vreg)
 }      
 
 static MonoType*
-type_from_stack_type (MonoInst *ins) {
+type_from_stack_type (MonoInst *ins)
+{
        switch (ins->type) {
        case STACK_I4: return &mono_defaults.int32_class->byval_arg;
        case STACK_I8: return &mono_defaults.int64_class->byval_arg;
@@ -941,7 +1001,8 @@ type_from_stack_type (MonoInst *ins) {
 }
 
 MonoType*
-mono_type_from_stack_type (MonoInst *ins) {
+mono_type_from_stack_type (MonoInst *ins)
+{
        return type_from_stack_type (ins);
 }
 
@@ -1232,8 +1293,6 @@ compare_by_interval_start_pos_func (gconstpointer a, gconstpointer b)
                return 1;
 }
 
-#ifndef DISABLE_JIT
-
 #if 0
 #define LSCAN_DEBUG(a) do { a; } while (0)
 #else
@@ -1792,17 +1851,6 @@ mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_s
        return offsets;
 }
 
-#else
-
-gint32*
-mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
-
-#endif /* DISABLE_JIT */
-
 #define EMUL_HIT_SHIFT 3
 #define EMUL_HIT_MASK ((1 << EMUL_HIT_SHIFT) - 1)
 /* small hit bitmap cache */
@@ -1851,7 +1899,8 @@ mini_register_opcode_emulation (int opcode, const char *name, const char *sigstr
 }
 
 static void
-print_dfn (MonoCompile *cfg) {
+print_dfn (MonoCompile *cfg)
+{
        int i, j;
        char *code;
        MonoBasicBlock *bb;
@@ -2004,7 +2053,6 @@ mono_verify_cfg (MonoCompile *cfg)
 void
 mono_destroy_compile (MonoCompile *cfg)
 {
-#ifndef DISABLE_JIT
        GSList *l;
 
        if (cfg->header)
@@ -2031,11 +2079,8 @@ mono_destroy_compile (MonoCompile *cfg)
        g_free (cfg->vars);
        g_free (cfg->exception_message);
        g_free (cfg);
-#endif
 }
 
-#ifndef DISABLE_JIT
-
 static MonoInst*
 mono_create_tls_get_offset (MonoCompile *cfg, int offset)
 {
@@ -2122,9 +2167,6 @@ mono_get_lmf_addr_intrinsic (MonoCompile* cfg)
        return mono_create_tls_get (cfg, TLS_KEY_LMF_ADDR);
 }
 
-#endif /* !DISABLE_JIT */
-
-
 void
 mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target)
 {
@@ -2196,8 +2238,6 @@ mono_add_var_location (MonoCompile *cfg, MonoInst *var, gboolean is_reg, int reg
                cfg->rgctx_loclist = g_slist_append_mempool (cfg->mempool, cfg->rgctx_loclist, entry);
 }
 
-#ifndef DISABLE_JIT
-
 static void
 mono_compile_create_vars (MonoCompile *cfg)
 {
@@ -2627,37 +2667,6 @@ mono_handle_out_of_line_bblock (MonoCompile *cfg)
        }
 }
 
-#endif /* #ifndef DISABLE_JIT */
-
-static MonoJitInfo*
-create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
-{
-       MonoDomain *domain = mono_get_root_domain ();
-       MonoJitInfo *jinfo;
-       guint8 *uw_info;
-       guint32 info_len;
-
-       if (info->uw_info) {
-               uw_info = info->uw_info;
-               info_len = info->uw_info_len;
-       } else {
-               uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
-       }
-
-       jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
-       jinfo->d.method = wrapper;
-       jinfo->code_start = info->code;
-       jinfo->code_size = info->code_size;
-       jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len);
-
-       if (!info->uw_info)
-               g_free (uw_info);
-
-       return jinfo;
-}
-
-#ifndef DISABLE_JIT
-
 static MonoJitInfo*
 create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
 {
@@ -2996,7 +3005,6 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
 
        return jinfo;
 }
-#endif
 
 /* Return whenever METHOD is a gsharedvt method */
 static gboolean
@@ -3039,8 +3047,6 @@ is_open_method (MonoMethod *method)
        return FALSE;
 }
 
-#ifndef DISABLE_JIT
-
 #if defined(__native_client_codegen__) || USE_COOP_GC
 
 static void
@@ -3098,6 +3104,42 @@ static void
 mono_insert_safepoints (MonoCompile *cfg)
 {
        MonoBasicBlock *bb;
+       if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+               WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method);
+#if defined(__native_client__) || defined(__native_client_codegen__)
+               gpointer poll_func = &mono_nacl_gc;
+#elif defined(USE_COOP_GC)
+               gpointer poll_func = &mono_threads_state_poll;
+#else
+               gpointer poll_func = NULL;
+#endif
+
+               if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER && info->d.icall.func == poll_func) {
+                       if (cfg->verbose_level > 1)
+                               printf ("SKIPPING SAFEPOINTS for the polling function icall\n");
+                       return;
+               }
+       }
+
+       if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
+               if (cfg->verbose_level > 1)
+                       printf ("SKIPPING SAFEPOINTS for native-to-managed wrappers.\n");
+               return;
+       }
+
+       if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+               WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method);
+
+               if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER &&
+                       (info->d.icall.func == mono_thread_interruption_checkpoint ||
+                       info->d.icall.func == mono_threads_finish_blocking ||
+                       info->d.icall.func == mono_threads_reset_blocking_start)) {
+                       /* These wrappers are called from the wrapper for the polling function, leading to potential stack overflow */
+                       if (cfg->verbose_level > 1)
+                               printf ("SKIPPING SAFEPOINTS for wrapper %s\n", cfg->method->name);
+                       return;
+               }
+       }
 
        if (cfg->verbose_level > 1)
                printf ("INSERTING SAFEPOINTS\n");
@@ -3569,6 +3611,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        if (!COMPILE_LLVM (cfg))
                mono_if_conversion (cfg);
 
+       MONO_SUSPEND_CHECK ();
+
        /* Depth-first ordering on basic blocks */
        cfg->bblocks = mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1));
 
@@ -3945,17 +3989,63 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        return cfg;
 }
 
-#else
+void*
+mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
+{
+       return mono_arch_instrument_epilog_full (cfg, func, p, enable_arguments, FALSE);
+}
 
-MonoCompile*
-mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
+void
+mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb)
 {
-       g_assert_not_reached ();
-       return NULL;
+       TryBlockHole *hole = mono_mempool_alloc (cfg->mempool, sizeof (TryBlockHole));
+       hole->clause = clause;
+       hole->start_offset = start - cfg->native_code;
+       hole->basic_block = bb;
+
+       cfg->try_block_holes = g_slist_append_mempool (cfg->mempool, cfg->try_block_holes, hole);
+}
+
+void
+mono_cfg_set_exception (MonoCompile *cfg, int type)
+{
+       cfg->exception_type = type;
 }
 
 #endif /* DISABLE_JIT */
 
+static MonoJitInfo*
+create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
+{
+       MonoDomain *domain = mono_get_root_domain ();
+       MonoJitInfo *jinfo;
+       guint8 *uw_info;
+       guint32 info_len;
+
+       if (info->uw_info) {
+               uw_info = info->uw_info;
+               info_len = info->uw_info_len;
+       } else {
+               uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+       }
+
+       jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
+       jinfo->d.method = wrapper;
+       jinfo->code_start = info->code;
+       jinfo->code_size = info->code_size;
+       jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len);
+
+       if (!info->uw_info)
+               g_free (uw_info);
+
+       return jinfo;
+}
+
+/*
+ * mono_jit_compile_method_inner:
+ *
+ *   Main entry point for the JIT.
+ */
 gpointer
 mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex)
 {
@@ -4276,32 +4366,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
        return code;
 }
 
-#ifndef DISABLE_JIT
-
-void*
-mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) {
-       return mono_arch_instrument_epilog_full (cfg, func, p, enable_arguments, FALSE);
-}
-
-void
-mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb)
-{
-       TryBlockHole *hole = mono_mempool_alloc (cfg->mempool, sizeof (TryBlockHole));
-       hole->clause = clause;
-       hole->start_offset = start - cfg->native_code;
-       hole->basic_block = bb;
-
-       cfg->try_block_holes = g_slist_append_mempool (cfg->mempool, cfg->try_block_holes, hole);
-}
-
-void
-mono_cfg_set_exception (MonoCompile *cfg, int type)
-{
-       cfg->exception_type = type;
-}
-
-#endif
-
 /* Dummy versions of some arch specific functions to avoid ifdefs at call sites */
 
 #ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
@@ -4365,101 +4429,6 @@ void mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
 }
 #endif
 
-#ifdef USE_JUMP_TABLES
-#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
-
-typedef struct MonoJumpTableChunk {
-       guint32 total;
-       guint32 active;
-       struct MonoJumpTableChunk *previous;
-       /* gpointer entries[total]; */
-} MonoJumpTableChunk;
-
-static MonoJumpTableChunk* g_jumptable;
-#define mono_jumptable_lock() mono_mutex_lock (&jumptable_mutex)
-#define mono_jumptable_unlock() mono_mutex_unlock (&jumptable_mutex)
-static mono_mutex_t jumptable_mutex;
-
-static  MonoJumpTableChunk*
-mono_create_jumptable_chunk (guint32 max_entries)
-{
-       guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
-       MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
-       chunk->total = max_entries;
-       return chunk;
-}
-
-void
-mono_jumptable_init (void)
-{
-       if (g_jumptable == NULL) {
-               mono_mutex_init_recursive (&jumptable_mutex);
-               g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
-       }
-}
-
-gpointer*
-mono_jumptable_add_entry (void)
-{
-       return mono_jumptable_add_entries (1);
-}
-
-gpointer*
-mono_jumptable_add_entries (guint32 entries)
-{
-       guint32 index;
-       gpointer *result;
-
-       mono_jumptable_init ();
-       mono_jumptable_lock ();
-       index = g_jumptable->active;
-       if (index + entries >= g_jumptable->total) {
-               /*
-                * Grow jumptable, by adding one more chunk.
-                * We cannot realloc jumptable, as there could be pointers
-                * to existing jump table entries in the code, so instead
-                * we just add one more chunk.
-                */
-               guint32 max_entries = entries;
-               MonoJumpTableChunk *new_chunk;
-
-               if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
-                       max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
-               new_chunk = mono_create_jumptable_chunk (max_entries);
-               /* Link old jumptable, so that we could free it up later. */
-               new_chunk->previous = g_jumptable;
-               g_jumptable = new_chunk;
-               index = 0;
-       }
-       g_jumptable->active = index + entries;
-       result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
-       mono_jumptable_unlock();
-
-       return result;
-}
-
-void
-mono_jumptable_cleanup (void)
-{
-       if (g_jumptable) {
-               MonoJumpTableChunk *current = g_jumptable, *prev;
-               while (current != NULL) {
-                       prev = current->previous;
-                       g_free (current);
-                       current = prev;
-               }
-               g_jumptable = NULL;
-               mono_mutex_destroy (&jumptable_mutex);
-       }
-}
-
-gpointer*
-mono_jumptable_get_entry (guint8 *code_ptr)
-{
-       return mono_arch_jumptable_entry_from_code (code_ptr);
-}
-#endif
-
 /*
  * mini_get_underlying_type:
  *
@@ -4482,6 +4451,31 @@ mini_jit_init (void)
 void
 mini_jit_cleanup (void)
 {
+#ifndef DISABLE_JIT
        g_free (emul_opcode_map);
        g_free (emul_opcode_opcodes);
+#endif
+}
+
+#ifdef DISABLE_JIT
+
+MonoCompile*
+mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void
+mono_destroy_compile (MonoCompile *cfg)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target)
+{
+       g_assert_not_reached ();
 }
+
+#endif /* DISABLE_JIT */
index 7a9df93158c7fcd1d992a47f377fff906450c4a7..b47a0ab2f8763752a2e6ba1984d86736315dd4fa 100644 (file)
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 120
+#define MONO_AOT_FILE_VERSION 121
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -307,9 +307,10 @@ typedef struct
        /* maps MonoMethod -> MonoJitDynamicMethodInfo */
        GHashTable *dynamic_code_hash;
        GHashTable *method_code_hash;
-       /* Maps methods to a RuntimeInvokeInfo structure */
+       /* Maps methods to a RuntimeInvokeInfo structure, protected by the associated MonoDomain lock */
        MonoConcurrentHashTable *runtime_invoke_hash;
        /* Maps MonoMethod to a GPtrArray containing sequence point locations */
+       /* Protected by the domain lock */
        GHashTable *seq_points;
        /* Debugger agent data */
        gpointer agent_info;
@@ -1326,9 +1327,6 @@ typedef enum {
        MONO_TRAMPOLINE_DELEGATE,
        MONO_TRAMPOLINE_RESTORE_STACK_PROT,
        MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
-       MONO_TRAMPOLINE_MONITOR_ENTER,
-       MONO_TRAMPOLINE_MONITOR_ENTER_V4,
-       MONO_TRAMPOLINE_MONITOR_EXIT,
        MONO_TRAMPOLINE_VCALL,
        MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
        MONO_TRAMPOLINE_NUM
@@ -1337,17 +1335,11 @@ typedef enum {
 /* These trampolines return normally to their caller */
 #define MONO_TRAMPOLINE_TYPE_MUST_RETURN(t)            \
        ((t) == MONO_TRAMPOLINE_RESTORE_STACK_PROT ||   \
-        (t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH ||     \
-        (t) == MONO_TRAMPOLINE_MONITOR_ENTER ||        \
-        (t) == MONO_TRAMPOLINE_MONITOR_ENTER_V4 ||     \
-        (t) == MONO_TRAMPOLINE_MONITOR_EXIT)
+        (t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
 
 /* These trampolines receive an argument directly in a register */
 #define MONO_TRAMPOLINE_TYPE_HAS_ARG(t)                \
-       ((t) == MONO_TRAMPOLINE_MONITOR_ENTER ||                \
-        (t) == MONO_TRAMPOLINE_MONITOR_ENTER_V4 ||             \
-        (t) == MONO_TRAMPOLINE_MONITOR_EXIT ||                 \
-        (t) == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
+       ((t) == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
 
 /* optimization flags */
 #define OPTFLAG(id,shift,name,descr) MONO_OPT_ ## id = 1 << shift,
@@ -2129,8 +2121,6 @@ void      mono_cprop_local                  (MonoCompile *cfg, MonoBasicBlock *b
 MonoInst* mono_compile_create_var           (MonoCompile *cfg, MonoType *type, int opcode);
 MonoInst* mono_compile_create_var_for_vreg  (MonoCompile *cfg, MonoType *type, int opcode, int vreg);
 void      mono_compile_make_var_load        (MonoCompile *cfg, MonoInst *dest, gssize var_index);
-MonoInst* mono_compile_create_var_load      (MonoCompile *cfg, gssize var_index);
-MonoInst* mono_compile_create_var_store     (MonoCompile *cfg, gssize var_index, MonoInst *value);
 MonoInst* mini_get_int_to_float_spill_area  (MonoCompile *cfg);
 MonoType* mono_type_from_stack_type         (MonoInst *ins);
 guint32   mono_alloc_ireg                   (MonoCompile *cfg) MONO_LLVM_INTERNAL;
@@ -2443,7 +2433,7 @@ void              mono_emit_unwind_op (MonoCompile *cfg, int when,
                                                                           int val);
 MonoTrampInfo*    mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops);
 void              mono_tramp_info_free (MonoTrampInfo *info);
-void              mono_tramp_info_register (MonoTrampInfo *info);
+void              mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain);
 int               mini_exception_id_by_name (const char *name);
 gboolean          mini_type_is_hfa (MonoType *t, int *out_nfields, int *out_esize) MONO_LLVM_INTERNAL;
 
@@ -2652,6 +2642,7 @@ void     mono_walk_stack_with_ctx               (MonoJitStackWalk func, MonoCont
 void     mono_walk_stack_with_state             (MonoJitStackWalk func, MonoThreadUnwindState *state, MonoUnwindOptions unwind_options, void *user_data);
 void     mono_walk_stack                        (MonoJitStackWalk func, MonoUnwindOptions options, void *user_data);
 gboolean mono_thread_state_init_from_sigctx     (MonoThreadUnwindState *ctx, void *sigctx);
+void     mono_thread_state_init                 (MonoThreadUnwindState *ctx);
 gboolean mono_thread_state_init_from_current    (MonoThreadUnwindState *ctx);
 gboolean mono_thread_state_init_from_monoctx    (MonoThreadUnwindState *ctx, MonoContext *mctx);
 
@@ -2689,7 +2680,6 @@ MonoBoolean ves_icall_get_frame_info            (gint32 skip, MonoBoolean need_f
                                                 MonoReflectionMethod **method, 
                                                 gint32 *iloffset, gint32 *native_offset,
                                                 MonoString **file, gint32 *line, gint32 *column);
-MonoString *ves_icall_System_Exception_get_trace (MonoException *exc);
 void mono_set_cast_details                      (MonoClass *from, MonoClass *to);
 
 /* Installs a function which is called when the runtime encounters an unhandled exception.
index 357a30d42ceb14b249f7a7c0ee1e2509cef178b7..c9f74b8e170b68359225bbc6e8a1fba44da6598c 100644 (file)
@@ -197,7 +197,7 @@ mono_get_seq_points (MonoDomain *domain, MonoMethod *method)
                shared_method = mini_get_shared_method (method);
        }
 
-       mono_domain_lock (domain);
+       mono_loader_lock ();
        seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, method);
        if (!seq_points && method->is_inflated) {
                /* generic sharing + aot */
@@ -205,7 +205,7 @@ mono_get_seq_points (MonoDomain *domain, MonoMethod *method)
                if (!seq_points)
                        seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, shared_method);
        }
-       mono_domain_unlock (domain);
+       mono_loader_unlock ();
 
        return seq_points;
 }
index 28e7644d29cf3ab2f77cb4d1acd16e612f454dc2..cdd2117aceacf51710bc8067e646a91657e0144c 100644 (file)
@@ -20,7 +20,7 @@ internal_init (void)
        if (keepalive_stacks)
                return;
        MONO_GC_REGISTER_ROOT_PINNING (keepalive_stacks);
-       keepalive_stacks = mono_g_hash_table_new (NULL, NULL);
+       keepalive_stacks = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_CONSERVATIVE_GC);
 }
 
 static void*
@@ -69,7 +69,7 @@ continuation_mark_frame (MonoContinuation *cont)
                ctx = new_ctx;
                if (endloop)
                        break;
-               if (strcmp (jinfo_get_method (ji)->name, "Mark") == 0)
+               if (!ji->is_trampoline && strcmp (jinfo_get_method (ji)->name, "Mark") == 0)
                        endloop = TRUE;
        } while (1);
 
index e40510a7563d895c0a6cafcbf33da5df140dc4a6..edeb4d3f5753d1f80c8df7e8063fed32c29cf781 100644 (file)
@@ -18,7 +18,6 @@
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/mono-debug-debugger.h>
-#include <mono/metadata/monitor.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/gc-internal.h>
 #include <mono/arch/amd64/amd64-codegen.h>
@@ -51,6 +50,7 @@ gpointer
 mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
 {
        guint8 *code, *start;
+       GSList *unwind_ops;
        int this_reg, size = NACL_SIZE (20, 32);
 
        MonoDomain *domain = mono_domain_get ();
@@ -59,6 +59,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
 
        start = code = mono_domain_code_reserve (domain, size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        amd64_alu_reg_imm (code, X86_ADD, this_reg, sizeof (MonoObject));
        /* FIXME: Optimize this */
        amd64_mov_reg_imm (code, AMD64_RAX, addr);
@@ -70,6 +72,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -82,6 +86,7 @@ gpointer
 mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
 {
        guint8 *code, *start;
+       GSList *unwind_ops;
        int buf_len;
 
        MonoDomain *domain = mono_domain_get ();
@@ -98,6 +103,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
 
        start = code = mono_domain_code_reserve (domain, buf_len);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        amd64_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, mrgctx);
        amd64_jump_code (code, addr);
        g_assert ((code - start) < buf_len);
@@ -106,6 +113,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -139,6 +148,11 @@ mono_arch_get_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *m, int vt_off
        return start;
 }
 
+#ifdef _WIN64
+// Workaround lack of Valgrind support for 64-bit Windows
+#define VALGRIND_DISCARD_TRANSLATIONS(...)
+#endif
+
 /*
  * mono_arch_patch_callsite:
  *
@@ -339,13 +353,12 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        offset += sizeof (MonoLMFTramp);
        lmf_offset = -offset;
 
-       framesize = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
+#ifdef TARGET_WIN32
+       /* Reserve space where the callee can save the argument registers */
+       offset += 4 * sizeof (mgreg_t);
+#endif
 
-       orig_rsp_to_rbp_offset = 0;
-       r11_save_code = code;
-       /* Reserve space for the mov_membase_reg to save R11 */
-       code += 5;
-       after_r11_save_code = code;
+       framesize = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
 
        // CFA = sp + 16 (the trampoline address is on the stack)
        cfa_offset = 16;
@@ -353,6 +366,12 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        // IP saved at CFA - 8
        mono_add_unwind_op_offset (unwind_ops, code, buf, AMD64_RIP, -8);
 
+       orig_rsp_to_rbp_offset = 0;
+       r11_save_code = code;
+       /* Reserve space for the mov_membase_reg to save R11 */
+       code += 5;
+       after_r11_save_code = code;
+
        /* Pop the return address off the stack */
        amd64_pop_reg (code, AMD64_R11);
        orig_rsp_to_rbp_offset += sizeof(mgreg_t);
@@ -440,10 +459,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        //amd64_breakpoint (code);
 #endif
 
-       if (tramp_type != MONO_TRAMPOLINE_MONITOR_ENTER &&
-               tramp_type != MONO_TRAMPOLINE_MONITOR_ENTER_V4 &&
-               tramp_type != MONO_TRAMPOLINE_MONITOR_EXIT &&
-               tramp_type != MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
+       if (tramp_type != MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
                /* Obtain the trampoline argument which is encoded in the instruction stream */
                if (aot) {
                        /* Load the GOT offset */
@@ -590,6 +606,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
 
        /* Restore stack */
        amd64_leave (code);
+       cfa_offset -= sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, AMD64_RSP, cfa_offset);
+
 
        if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type)) {
                /* Load result */
@@ -697,7 +716,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
        int i;
        gboolean mrgctx;
        MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
+       GSList *unwind_ops;
 
        mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
        index = MONO_RGCTX_SLOT_INDEX (slot);
@@ -786,317 +805,6 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
        return buf;
 }
 
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
-       guint8 *tramp;
-       guint8 *code, *buf;
-       guint8 *jump_obj_null, *jump_sync_null, *jump_cmpxchg_failed, *jump_other_owner, *jump_tid, *jump_sync_thin_hash = NULL;
-       guint8 *jump_lock_taken_true = NULL;
-       int tramp_size;
-       int status_offset, nest_offset;
-       MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
-       int obj_reg = MONO_AMD64_ARG_REG1;
-       int lock_taken_reg = MONO_AMD64_ARG_REG2;
-       int sync_reg = MONO_AMD64_ARG_REG3;
-       int tid_reg = MONO_AMD64_ARG_REG4;
-       int status_reg = AMD64_RAX;
-
-       g_assert (MONO_ARCH_MONITOR_OBJECT_REG == obj_reg);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
-       g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG == lock_taken_reg);
-#else
-       g_assert (!is_v4);
-#endif
-
-       mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
-       status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
-       nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
-       tramp_size = 128;
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       unwind_ops = mono_arch_get_cie_program ();
-
-       if (!aot && mono_thread_get_tls_offset () != -1) {
-               /* MonoObject* obj is in obj_reg */
-               /* is obj null? */
-               amd64_test_reg_reg (code, obj_reg, obj_reg);
-               /* if yes, jump to actual trampoline */
-               jump_obj_null = code;
-               amd64_branch8 (code, X86_CC_Z, -1, 1);
-
-               if (is_v4) {
-                       amd64_test_membase_imm (code, lock_taken_reg, 0, 1);
-                       /* if *lock_taken is 1, jump to actual trampoline */
-                       jump_lock_taken_true = code;
-                       x86_branch8 (code, X86_CC_NZ, -1, 1);
-               }
-
-               /* load obj->synchronization to sync_reg */
-               amd64_mov_reg_membase (code, sync_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8);
-
-               if (mono_gc_is_moving ()) {
-                       /*if bit zero is set it's a thin hash*/
-                       /*FIXME use testb encoding*/
-                       amd64_test_reg_imm (code, sync_reg, 0x01);
-                       jump_sync_thin_hash = code;
-                       amd64_branch8 (code, X86_CC_NE, -1, 1);
-
-                       /*clear bits used by the gc*/
-                       amd64_alu_reg_imm (code, X86_AND, sync_reg, ~0x3);
-               }
-
-               /* is synchronization null? */
-               amd64_test_reg_reg (code, sync_reg, sync_reg);
-               /* if yes, jump to actual trampoline */
-               jump_sync_null = code;
-               amd64_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* load MonoInternalThread* into tid_reg */
-               code = mono_amd64_emit_tls_get (code, tid_reg, mono_thread_get_tls_offset ());
-               /* load TID into tid_reg */
-               amd64_mov_reg_membase (code, tid_reg, tid_reg, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
-
-               /* is synchronization->owner free */
-               amd64_mov_reg_membase (code, status_reg, sync_reg, status_offset, 4);
-               amd64_test_reg_imm_size (code, status_reg, OWNER_MASK, 4);
-               /* if not, jump to next case */
-               jump_tid = code;
-               amd64_branch8 (code, X86_CC_NZ, -1, 1);
-
-               /* if yes, try a compare-exchange with the TID */
-               g_assert (tid_reg != X86_EAX);
-               /* Form new status in tid_reg */
-               amd64_alu_reg_reg_size (code, X86_OR, tid_reg, status_reg, 4);
-               /* compare and exchange */
-               amd64_prefix (code, X86_LOCK_PREFIX);
-               amd64_cmpxchg_membase_reg_size (code, sync_reg, status_offset, tid_reg, 4);
-               /* if not successful, jump to actual trampoline */
-               jump_cmpxchg_failed = code;
-               amd64_branch8 (code, X86_CC_NZ, -1, 1);
-               /* if successful, return */
-               if (is_v4)
-                       amd64_mov_membase_imm (code, lock_taken_reg, 0, 1, 1);
-               amd64_ret (code);
-
-               /* next case: synchronization->owner is not null */
-               x86_patch (jump_tid, code);
-               /* is synchronization->owner == TID? */
-               amd64_alu_reg_imm_size (code, X86_AND, status_reg, OWNER_MASK, 4);
-               amd64_alu_reg_reg_size (code, X86_CMP, status_reg, tid_reg, 4);
-               /* if not, jump to actual trampoline */
-               jump_other_owner = code;
-               amd64_branch8 (code, X86_CC_NZ, -1, 1);
-               /* if yes, increment nest */
-               amd64_inc_membase_size (code, sync_reg, nest_offset, 4);
-               /* return */
-               if (is_v4)
-                       amd64_mov_membase_imm (code, lock_taken_reg, 0, 1, 1);
-               amd64_ret (code);
-
-               x86_patch (jump_obj_null, code);
-               if (jump_sync_thin_hash)
-                       x86_patch (jump_sync_thin_hash, code);
-               x86_patch (jump_sync_null, code);
-               x86_patch (jump_cmpxchg_failed, code);
-               x86_patch (jump_other_owner, code);
-               if (is_v4)
-                       x86_patch (jump_lock_taken_true, code);
-       }
-
-       /* jump to the actual trampoline */
-       if (MONO_AMD64_ARG_REG1 != obj_reg)
-               amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, obj_reg, sizeof (mgreg_t));
-
-       if (aot) {
-               if (is_v4)
-                       code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_enter_v4");
-               else
-                       code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_enter");
-               amd64_jump_reg (code, AMD64_R11);
-       } else {
-               if (is_v4)
-                       tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER_V4, mono_get_root_domain (), NULL);
-               else
-                       tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER, mono_get_root_domain (), NULL);
-
-               /* jump to the actual trampoline */
-               amd64_jump_code (code, tramp);
-       }
-
-       nacl_global_codeman_validate (&buf, tramp_size, &code);
-
-       mono_arch_flush_icache (code, code - buf);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-       g_assert (code - buf <= tramp_size);
-
-       if (is_v4)
-               *info = mono_tramp_info_create ("monitor_enter_v4_trampoline", buf, code - buf, ji, unwind_ops);
-       else
-               *info = mono_tramp_info_create ("monitor_enter_trampoline", buf, code - buf, ji, unwind_ops);
-
-       return buf;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
-       guint8 *tramp;
-       guint8 *code, *buf;
-       guint8 *jump_obj_null, *jump_have_waiters, *jump_sync_null, *jump_not_owned, *jump_cmpxchg_failed;
-       guint8 *jump_next, *jump_sync_thin_hash = NULL;
-       int tramp_size;
-       int status_offset, nest_offset;
-       MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
-       int obj_reg = MONO_AMD64_ARG_REG1;
-       int sync_reg = MONO_AMD64_ARG_REG2;
-       int status_reg = MONO_AMD64_ARG_REG3;
-
-       g_assert (obj_reg == MONO_ARCH_MONITOR_OBJECT_REG);
-
-       mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
-       status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
-       nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
-       tramp_size = 112;
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       unwind_ops = mono_arch_get_cie_program ();
-
-       if (!aot && mono_thread_get_tls_offset () != -1) {
-               /* MonoObject* obj is in obj_reg */
-               /* is obj null? */
-               amd64_test_reg_reg (code, obj_reg, obj_reg);
-               /* if yes, jump to actual trampoline */
-               jump_obj_null = code;
-               amd64_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* load obj->synchronization to RCX */
-               amd64_mov_reg_membase (code, sync_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8);
-
-               if (mono_gc_is_moving ()) {
-                       /*if bit zero is set it's a thin hash*/
-                       /*FIXME use testb encoding*/
-                       amd64_test_reg_imm (code, sync_reg, 0x01);
-                       jump_sync_thin_hash = code;
-                       amd64_branch8 (code, X86_CC_NE, -1, 1);
-
-                       /*clear bits used by the gc*/
-                       amd64_alu_reg_imm (code, X86_AND, sync_reg, ~0x3);
-               }
-
-               /* is synchronization null? */
-               amd64_test_reg_reg (code, sync_reg, sync_reg);
-               /* if yes, jump to actual trampoline */
-               jump_sync_null = code;
-               amd64_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* next case: synchronization is not null */
-               /* load MonoInternalThread* into RAX */
-               code = mono_amd64_emit_tls_get (code, AMD64_RAX, mono_thread_get_tls_offset ());
-               /* load TID into RAX */
-               amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RAX, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
-               /* is synchronization->owner == TID */
-               amd64_mov_reg_membase (code, status_reg, sync_reg, status_offset, 4);
-               amd64_alu_reg_reg_size (code, X86_XOR, AMD64_RAX, status_reg, 4);
-               amd64_test_reg_imm_size (code, AMD64_RAX, OWNER_MASK, 4);
-
-               /* if no, jump to actual trampoline */
-               jump_not_owned = code;
-               amd64_branch8 (code, X86_CC_NZ, -1, 1);
-
-               /* next case: synchronization->owner == TID */
-               /* is synchronization->nest == 1 */
-               amd64_alu_membase_imm_size (code, X86_CMP, sync_reg, nest_offset, 1, 4);
-               /* if not, jump to next case */
-               jump_next = code;
-               amd64_branch8 (code, X86_CC_NZ, -1, 1);
-               /* if yes, is synchronization->entry_count greater than zero */
-               amd64_test_reg_imm_size (code, status_reg, ENTRY_COUNT_WAITERS, 4);
-               /* if not, jump to actual trampoline */
-               jump_have_waiters = code;
-               amd64_branch8 (code, X86_CC_NZ, -1 , 1);
-               /* if yes, try to set synchronization->owner to null and return */
-               g_assert (status_reg != AMD64_RAX);
-               /* old status in RAX */
-               amd64_mov_reg_reg (code, AMD64_RAX, status_reg, 4);
-               /* form new status */
-               amd64_alu_reg_imm_size (code, X86_AND, status_reg, ENTRY_COUNT_MASK, 4);
-               /* compare and exchange */
-               amd64_prefix (code, X86_LOCK_PREFIX);
-               amd64_cmpxchg_membase_reg_size (code, sync_reg, status_offset, status_reg, 4);
-               /* if not successful, jump to actual trampoline */
-               jump_cmpxchg_failed = code;
-               amd64_branch8 (code, X86_CC_NZ, -1, 1);
-               amd64_ret (code);
-
-               /* next case: synchronization->nest is not 1 */
-               x86_patch (jump_next, code);
-               /* decrease synchronization->nest and return */
-               amd64_dec_membase_size (code, sync_reg, nest_offset, 4);
-               amd64_ret (code);
-
-               if (jump_sync_thin_hash)
-                       x86_patch (jump_sync_thin_hash, code);
-               x86_patch (jump_obj_null, code);
-               x86_patch (jump_have_waiters, code);
-               x86_patch (jump_not_owned, code);
-               x86_patch (jump_cmpxchg_failed, code);
-               x86_patch (jump_sync_null, code);
-       }
-
-       /* jump to the actual trampoline */
-       if (MONO_AMD64_ARG_REG1 != obj_reg)
-               amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, obj_reg, sizeof (mgreg_t));
-
-       if (aot) {
-               code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_exit");
-               amd64_jump_reg (code, AMD64_R11);
-       } else {
-               tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_EXIT, mono_get_root_domain (), NULL);
-               amd64_jump_code (code, tramp);
-       }
-
-       nacl_global_codeman_validate (&buf, tramp_size, &code);
-
-       mono_arch_flush_icache (code, code - buf);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-       g_assert (code - buf <= tramp_size);
-
-       *info = mono_tramp_info_create ("monitor_exit_trampoline", buf, code - buf, ji, unwind_ops);
-
-       return buf;
-}
-
-#else
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
-
-#endif
-
 void
 mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
 {
@@ -1125,12 +833,14 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
        guint8 *code, *buf;
        int tramp_size = 64;
        MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
+       GSList *unwind_ops;
 
        g_assert (!aot);
 
        code = buf = mono_global_codeman_reserve (tramp_size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        /*
        This trampoline restore the call chain of the handler block then jumps into the code that deals with it.
        */
@@ -1139,13 +849,16 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
                amd64_mov_reg_membase (code, MONO_AMD64_ARG_REG1, MONO_AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8);
                /* Simulate a call */
                amd64_push_reg (code, AMD64_RAX);
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 16);
                amd64_jump_code (code, tramp);
        } else {
                /*Slow path uses a c helper*/
                amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RSP, 8);
                amd64_mov_reg_imm (code, AMD64_RAX, tramp);
                amd64_push_reg (code, AMD64_RAX);
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 16);
                amd64_push_reg (code, AMD64_RAX);
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 24);
                amd64_jump_code (code, handler_block_trampoline_helper);
        }
 
@@ -1211,7 +924,15 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
 
        code = buf = mono_global_codeman_reserve (tramp_size);
 
-       framesize = sizeof (MonoContext);
+       framesize = 0;
+#ifdef TARGET_WIN32
+       /* Reserve space where the callee can save the argument registers */
+       framesize += 4 * sizeof (mgreg_t);
+#endif
+
+       ctx_offset = framesize;
+       framesize += sizeof (MonoContext);
+
        framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT);
 
        // CFA = sp + 8
@@ -1229,7 +950,6 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
        mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, AMD64_RBP);
        amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, framesize);
 
-       ctx_offset = 0;
        gregs_offset = ctx_offset + MONO_STRUCT_OFFSET (MonoContext, gregs);
 
        /* Initialize a MonoContext structure on the stack */
@@ -1271,6 +991,8 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
        amd64_mov_membase_reg (code, AMD64_RBP, sizeof (mgreg_t), AMD64_R11, sizeof (mgreg_t));
 
        amd64_leave (code);
+       cfa_offset -= sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, AMD64_RSP, cfa_offset);
        amd64_ret (code);
 
        mono_arch_flush_icache (code, code - buf);
index 85b29242e57fe1c42ff37a779e75379378898dc8..156a5ee54fb561dc72c3573cd46e9de525c14eaa 100644 (file)
@@ -218,9 +218,6 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        /* The offset where lr was saved inside the regsave area */
        lr_offset = 13 * sizeof (mgreg_t);
 
-       // FIXME: Finish the unwind info, the current info allows us to unwind
-       // when the trampoline is not in the epilog
-
        // CFA = SP + (num registers pushed) * 4
        cfa_offset = 14 * sizeof (mgreg_t);
        mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset);
@@ -425,10 +422,16 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
         * Note that IP has been conveniently set to the method addr.
         */
        ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, STACK - regsave_size);
+       cfa_offset -= STACK - regsave_size;
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
        ARM_POP_NWB (code, 0x5fff);
+       mono_add_unwind_op_same_value (unwind_ops, code, buf, ARMREG_LR);
        if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
                ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_IP);
        ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, regsave_size);
+       cfa_offset -= regsave_size;
+       g_assert (cfa_offset == 0);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
        if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type))
                code = emit_bx (code, ARMREG_LR);
        else
@@ -571,6 +574,7 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
 {
        guint8 *code, *start;
        MonoDomain *domain = mono_domain_get ();
+       GSList *unwind_ops;
 #ifdef USE_JUMP_TABLES
        gpointer *jte;
        guint32 size = 20;
@@ -580,6 +584,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
 
        start = code = mono_domain_code_reserve (domain, size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
 #ifdef USE_JUMP_TABLES
        jte = mono_jumptable_add_entry ();
        code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
@@ -599,6 +605,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        /*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
        g_print ("unbox code is at %p for method at %p\n", start, addr);*/
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -606,6 +614,7 @@ gpointer
 mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
 {
        guint8 *code, *start;
+       GSList *unwind_ops;
 #ifdef USE_JUMP_TABLES
        int buf_len = 20;
        gpointer *jte;
@@ -616,6 +625,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
 
        start = code = mono_domain_code_reserve (domain, buf_len);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
 #ifdef USE_JUMP_TABLES
        jte = mono_jumptable_add_entries (2);
        code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP);
@@ -638,6 +649,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -674,7 +687,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
 
        code = buf = mono_global_codeman_reserve (tramp_size);
 
-       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
+       unwind_ops = mono_arch_get_cie_program ();
 
        rgctx_null_jumps = g_malloc (sizeof (guint8*) * (depth + 2));
        njumps = 0;
@@ -783,7 +796,7 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo
 
        code = buf = mono_global_codeman_reserve (tramp_size);
 
-       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
+       unwind_ops = mono_arch_get_cie_program ();
 
        // FIXME: Currently, we always go to the slow path.
        /* Load trampoline addr */
@@ -822,6 +835,8 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
 
        code = buf = mono_global_codeman_reserve (tramp_size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD, NULL, NULL);
 
        /*
@@ -1100,6 +1115,8 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint
        mono_arch_flush_icache (buf, code - buf);
        mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, buf, code - buf, NULL, NULL), domain);
+
        return buf;
 }
 
index f0ca392d9c55c97355b605918d7d993562cdc802..2b4af7f8fe2ac613acd6667519fa76134d17d8a0 100644 (file)
@@ -67,6 +67,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        desc [0] = buf;
        desc [1] = func_gp;
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, buf, code.buf - buf, NULL, NULL), domain);
+
        return desc;
 }
 
index bf35f84ff349c7a63835d1a305d054c73a012bae..37f17a47c89b3d7c20e638236364ae6fa25b4533 100644 (file)
@@ -53,6 +53,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        /*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
        g_print ("unbox code is at %p for method at %p\n", start, addr);*/
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
@@ -324,6 +326,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
 
        mono_arch_flush_icache (start, code - start);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
index 1c723aa2ebb110ba89fd6870a2d377b2c6940988..32ab65ba8cda81118f2a16007cef51fda25a7b5a 100644 (file)
@@ -104,6 +104,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        /*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
        g_print ("unbox code is at %p for method at %p\n", start, addr);*/
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
@@ -149,6 +151,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
        mono_arch_flush_icache (start, code - start);
        g_assert ((code - start) <= size);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
index a9ec6cf67e0996794db4ed67ad4268562c00dd12..e70f5c55c08a1142f9c4bef9ec9e30dacc25e675 100644 (file)
@@ -41,7 +41,6 @@
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/gc-internal.h>
 #include <mono/metadata/marshal.h>
-#include <mono/metadata/monitor.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/arch/s390x/s390x-codegen.h>
@@ -109,6 +108,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, method);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }
 
@@ -402,18 +403,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
        /*----------------------------------------------------------*/
        code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);
 
-       switch (tramp_type) {
-       /*
-        * Monitor tramps have the object in r2
-        */
-       case MONO_TRAMPOLINE_MONITOR_ENTER:
-       case MONO_TRAMPOLINE_MONITOR_ENTER_V4:
-       case MONO_TRAMPOLINE_MONITOR_EXIT:
-               s390_lgr (buf, s390_r1, s390_r2);
-               break;
-       default :
-               S390_SET  (buf, s390_r1, arg1);
-       }
+       S390_SET  (buf, s390_r1, arg1);
        displace = (tramp - buf) / 2;
        s390_jg   (buf, displace);
 
@@ -580,6 +570,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m,
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return(start);
 }      
 
@@ -658,299 +650,3 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
 }
 
 /*========================= End of Function ========================*/
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_create_monitor_enter_trampoline         */
-/*                                                                  */
-/* Function    -                                                   */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
-       guint8  *tramp,
-               *code, *buf;
-       gint16  *jump_obj_null, 
-               *jump_sync_null, 
-               *jump_cs_failed, 
-               *jump_other_owner, 
-               *jump_tid, 
-               *jump_sync_thin_hash = NULL,
-               *jump_lock_taken_true = NULL;
-       int tramp_size,
-           status_reg = s390_r0,
-           lock_taken_reg = s390_r1,
-           obj_reg = s390_r2,
-           sync_reg = s390_r3,
-           tid_reg = s390_r4,
-           status_offset,
-           nest_offset;
-       MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
-
-       g_assert (MONO_ARCH_MONITOR_OBJECT_REG == obj_reg);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
-       g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG == lock_taken_reg);
-#else
-       g_assert (!is_v4);
-#endif
-
-       mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
-       status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
-       nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
-       tramp_size = 160;
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       unwind_ops = mono_arch_get_cie_program ();
-
-       if (mono_thread_get_tls_offset () != -1) {
-               /* MonoObject* obj is in obj_reg */
-               /* is obj null? */
-               s390_ltgr (code, obj_reg, obj_reg);
-               /* if yes, jump to actual trampoline */
-               s390_jz (code, 0); CODEPTR(code, jump_obj_null);
-
-               if (is_v4) {
-                       s390_cli (code, lock_taken_reg, 0, 1);
-                       /* if *lock_taken is 1, jump to actual trampoline */
-                       s390_je (code, 0); CODEPTR(code, jump_lock_taken_true);
-               }
-
-               /* load obj->synchronization to sync_reg */
-               s390_lg (code, sync_reg, 0, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation));
-
-               if (mono_gc_is_moving ()) {
-                       /*if bit zero is set it's a thin hash*/
-                       s390_tmll (code, sync_reg, 1);
-                       s390_jo  (code, 0); CODEPTR(code, jump_sync_thin_hash);
-
-                       /* Clear bits used by the gc */
-                       s390_nill (code, sync_reg, ~0x3);
-               }
-
-               /* is synchronization null? */
-               s390_ltgr (code, sync_reg, sync_reg);
-               /* if yes, jump to actual trampoline */
-               s390_jz (code, 0); CODEPTR(code, jump_sync_null);
-
-               /* load MonoInternalThread* into tid_reg */
-               s390_ear (code, s390_r5, 0);
-               s390_sllg(code, s390_r5, s390_r5, 0, 32);
-               s390_ear (code, s390_r5, 1);
-               /* load tid */
-               s390_lg  (code, tid_reg, 0, s390_r5, mono_thread_get_tls_offset ());
-               s390_lgf (code, tid_reg, 0, tid_reg, MONO_STRUCT_OFFSET (MonoInternalThread, small_id));
-
-               /* is synchronization->owner free */
-               s390_lgf  (code, status_reg, 0, sync_reg, status_offset);
-               s390_nilf (code, status_reg, OWNER_MASK);
-               /* if not, jump to next case */
-               s390_jnz  (code, 0); CODEPTR(code, jump_tid);
-
-               /* if yes, try a compare-exchange with the TID */
-               /* Form new status in tid_reg */
-               s390_xr (code, tid_reg, status_reg);
-               /* compare and exchange */
-               s390_cs (code, status_reg, tid_reg, sync_reg, status_offset);
-               s390_jnz (code, 0); CODEPTR(code, jump_cs_failed);
-               /* if successful, return */
-               if (is_v4)
-                       s390_mvi (code, lock_taken_reg, 0, 1);
-               s390_br (code, s390_r14);
-
-               /* next case: synchronization->owner is not null */
-               PTRSLOT(code, jump_tid);
-               /* is synchronization->owner == TID? */
-               s390_nilf (code, status_reg, OWNER_MASK);
-               s390_cr (code, status_reg, tid_reg);
-               /* if not, jump to actual trampoline */
-               s390_jnz (code, 0); CODEPTR(code, jump_other_owner);
-               /* if yes, increment nest */
-               s390_lgf (code, s390_r5, 0, sync_reg, nest_offset);
-               s390_ahi (code, s390_r5, 1);
-               s390_st  (code, s390_r5, 0, sync_reg, nest_offset);
-               /* return */
-               if (is_v4)
-                       s390_mvi (code, lock_taken_reg, 0, 1);
-               s390_br (code, s390_r14);
-
-               PTRSLOT (code, jump_obj_null);
-               if (jump_sync_thin_hash)
-                       PTRSLOT (code, jump_sync_thin_hash);
-               PTRSLOT (code, jump_sync_null);
-               PTRSLOT (code, jump_cs_failed);
-               PTRSLOT (code, jump_other_owner);
-               if (is_v4)
-                       PTRSLOT (code, jump_lock_taken_true);
-       }
-
-       /* jump to the actual trampoline */
-       if (is_v4)
-               tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER_V4, mono_get_root_domain (), NULL);
-       else
-               tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER, mono_get_root_domain (), NULL);
-
-       /* jump to the actual trampoline */
-       S390_SET (code, s390_r1, tramp);
-       s390_br (code, s390_r1);
-
-       mono_arch_flush_icache (code, code - buf);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-       g_assert (code - buf <= tramp_size);
-
-       if (info) {
-               if (is_v4)
-                       *info = mono_tramp_info_create ("monitor_enter_v4_trampoline", buf, code - buf, ji, unwind_ops);
-               else
-                       *info = mono_tramp_info_create ("monitor_enter_trampoline", buf, code - buf, ji, unwind_ops);
-       }
-
-       return buf;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_create_monitor_exit_trampoline          */
-/*                                                                  */
-/* Function    -                                                   */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
-       guint8  *tramp,
-               *code, *buf;
-       gint16  *jump_obj_null, 
-               *jump_have_waiters, 
-               *jump_sync_null, 
-               *jump_not_owned, 
-               *jump_cs_failed,
-               *jump_next,
-               *jump_sync_thin_hash = NULL;
-       int     tramp_size,
-               status_offset, nest_offset;
-       MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
-       int     obj_reg = s390_r2,
-               sync_reg = s390_r3,
-               status_reg = s390_r4;
-
-       g_assert (obj_reg == MONO_ARCH_MONITOR_OBJECT_REG);
-
-       mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
-       status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
-       nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
-       tramp_size = 160;
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       unwind_ops = mono_arch_get_cie_program ();
-
-       if (mono_thread_get_tls_offset () != -1) {
-               /* MonoObject* obj is in obj_reg */
-               /* is obj null? */
-               s390_ltgr (code, obj_reg, obj_reg);
-               /* if yes, jump to actual trampoline */
-               s390_jz (code, 0); CODEPTR(code, jump_obj_null);
-
-               /* load obj->synchronization to RCX */
-               s390_lg (code, sync_reg, 0, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation));
-
-               if (mono_gc_is_moving ()) {
-                       /*if bit zero is set it's a thin hash*/
-                       s390_tmll (code, sync_reg, 1);
-                       s390_jo   (code, 0); CODEPTR(code, jump_sync_thin_hash);
-
-                       /* Clear bits used by the gc */
-                       s390_nill (code, sync_reg, ~0x3);
-               }
-
-               /* is synchronization null? */
-               s390_ltgr (code, sync_reg, sync_reg);
-               /* if yes, jump to actual trampoline */
-               s390_jz (code, 0); CODEPTR(code, jump_sync_null);
-
-               /* next case: synchronization is not null */
-               /* load MonoInternalThread* into r5 */
-               s390_ear (code, s390_r5, 0);
-               s390_sllg(code, s390_r5, s390_r5, 0, 32);
-               s390_ear (code, s390_r5, 1);
-               /* load TID into r1 */
-               s390_lg  (code, s390_r1, 0, s390_r5, mono_thread_get_tls_offset ());
-               s390_lgf (code, s390_r1, 0, s390_r1, MONO_STRUCT_OFFSET (MonoInternalThread, small_id));
-               /* is synchronization->owner == TID */
-               s390_lgf (code, status_reg, 0, sync_reg, status_offset);
-               s390_xr  (code, s390_r1, status_reg);
-               s390_tmlh (code, s390_r1, OWNER_MASK);
-               /* if not, jump to actual trampoline */
-               s390_jno (code, 0); CODEPTR(code, jump_not_owned);
-
-               /* next case: synchronization->owner == TID */
-               /* is synchronization->nest == 1 */
-               s390_lgf (code, s390_r0, 0, sync_reg, nest_offset);
-               s390_chi (code, s390_r0, 1);
-               /* if not, jump to next case */
-               s390_jne (code, 0); CODEPTR(code, jump_next);
-               /* if yes, is synchronization->entry_count greater than zero */
-               s390_cfi (code, status_reg, ENTRY_COUNT_WAITERS);
-               /* if not, jump to actual trampoline */
-               s390_jnz (code, 0); CODEPTR(code, jump_have_waiters);
-               /* if yes, try to set synchronization->owner to null and return */
-               /* old status in s390_r0 */
-               s390_lgfr (code, s390_r0, status_reg);
-               /* form new status */
-               s390_nilf (code, status_reg, ENTRY_COUNT_MASK);
-               /* compare and exchange */
-               s390_cs (code, s390_r0, status_reg, sync_reg, status_offset);
-               /* if not successful, jump to actual trampoline */
-               s390_jnz (code, 0); CODEPTR(code, jump_cs_failed);
-               s390_br  (code, s390_r14);
-
-               /* next case: synchronization->nest is not 1 */
-               PTRSLOT (code, jump_next);
-               /* decrease synchronization->nest and return */
-               s390_lgf (code, s390_r0, 0, sync_reg, nest_offset);
-               s390_ahi (code, s390_r0, -1);
-               s390_st  (code, s390_r0, 0, sync_reg, nest_offset);
-               s390_br  (code, s390_r14);
-
-               PTRSLOT (code, jump_obj_null);
-               if (jump_sync_thin_hash)
-                       PTRSLOT (code, jump_sync_thin_hash);
-               PTRSLOT (code, jump_have_waiters);
-               PTRSLOT (code, jump_not_owned);
-               PTRSLOT (code, jump_cs_failed);
-               PTRSLOT (code, jump_sync_null);
-       }
-
-       /* jump to the actual trampoline */
-       tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_EXIT, mono_get_root_domain (), NULL);
-
-       S390_SET (code, s390_r1, tramp);
-       s390_br (code, s390_r1);
-
-       mono_arch_flush_icache (code, code - buf);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-       g_assert (code - buf <= tramp_size);
-
-       if (info)
-               *info = mono_tramp_info_create ("monitor_exit_trampoline", buf, code - buf, ji, unwind_ops);
-
-       return buf;
-}
-
-/*========================= End of Function ========================*/
-#endif
index d390ed4dcc6be5714d2e07d9d5d8db6b61b9c53e..99143b723b30291f156655b305b3bc19b4135f81 100644 (file)
@@ -51,6 +51,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
 
        mono_arch_flush_icache (start, code - start);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), NULL);
+
        return start;
 }
 
index 9a887c435db9890aa5deed680b7d3e9d79ccefac..6e79922512c9f3b165e62ebace0af1d2de63b81f 100644 (file)
@@ -17,7 +17,6 @@
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/mono-debug-debugger.h>
-#include <mono/metadata/monitor.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/gc-internal.h>
 #include <mono/arch/x86/x86-codegen.h>
@@ -26,6 +25,7 @@
 
 #include "mini.h"
 #include "mini-x86.h"
+#include "debugger-agent.h"
 
 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
 
@@ -44,9 +44,12 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        guint8 *code, *start;
        int this_pos = 4, size = NACL_SIZE(16, 32);
        MonoDomain *domain = mono_domain_get ();
+       GSList *unwind_ops;
 
        start = code = mono_domain_code_reserve (domain, size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, sizeof (MonoObject));
        x86_jump_code (code, addr);
        g_assert ((code - start) < size);
@@ -54,6 +57,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        nacl_domain_code_validate (domain, &start, size, &code);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -62,6 +67,7 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
 {
        guint8 *code, *start;
        int buf_len;
+       GSList *unwind_ops;
 
        MonoDomain *domain = mono_domain_get ();
 
@@ -69,6 +75,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
 
        start = code = mono_domain_code_reserve (domain, buf_len);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        x86_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, mrgctx);
        x86_jump_code (code, addr);
        g_assert ((code - start) <= buf_len);
@@ -77,6 +85,8 @@ mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericCo
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
@@ -247,8 +257,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        GSList *unwind_ops = NULL;
        MonoJumpInfo *ji = NULL;
        int i, offset, frame_size, regarray_offset, lmf_offset, caller_ip_offset, arg_offset;
-
-       unwind_ops = mono_arch_get_cie_program ();
+       int cfa_offset; /* cfa = cfa_reg + cfa_offset */
 
        code = buf = mono_global_codeman_reserve (256);
 
@@ -257,8 +266,6 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
         * the ret address is at: esp + (pushed_args + 1) * sizeof (gpointer)
         */
 
-       // FIXME: Unwind info
-
        /* Compute frame offsets relative to the frame pointer %ebp */
        arg_offset = sizeof (mgreg_t);
        caller_ip_offset = 2 * sizeof (mgreg_t);
@@ -271,9 +278,21 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        offset += 4 * sizeof (mgreg_t);
        frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
 
+       /* ret addr and arg are on the stack */
+       cfa_offset = 2 * sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset);
+       // IP saved at CFA - 4
+       mono_add_unwind_op_offset (unwind_ops, code, buf, X86_NREG, -4);
+
        /* Allocate frame */
        x86_push_reg (code, X86_EBP);
+       cfa_offset += sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+       mono_add_unwind_op_offset (unwind_ops, code, buf, X86_EBP, -cfa_offset);
+
        x86_mov_reg_reg (code, X86_EBP, X86_ESP, sizeof (mgreg_t));
+       mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, X86_EBP);
+
        /* There are three words on the stack, adding + 4 aligns the stack to 16, which is needed on osx */
        x86_alu_reg_imm (code, X86_SUB, X86_ESP, frame_size + sizeof (mgreg_t));
 
@@ -413,17 +432,24 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
 
        /* Restore frame */
        x86_leave (code);
+       cfa_offset -= sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset);
+       mono_add_unwind_op_same_value (unwind_ops, code, buf, X86_EBP);
 
        if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type)) {
                /* Load the value returned by the trampoline */
                x86_mov_reg_membase (code, X86_EAX, X86_ESP, 0, 4);
                /* The trampoline returns normally, pop the trampoline argument */
                x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
+               cfa_offset -= sizeof (mgreg_t);
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
                x86_ret (code);
        } else {
                /* The trampoline argument is at the top of the stack, and it contains the address we need to branch to */
                if (tramp_type == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
                        x86_pop_reg (code, X86_EAX);
+                       cfa_offset -= sizeof (mgreg_t);
+                       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
                        x86_alu_reg_imm (code, X86_ADD, X86_ESP, 0x8);
                        x86_jump_reg (code, X86_EAX);
                } else {
@@ -613,342 +639,6 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo
        return buf;
 }
 
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-/*
- * The code produced by this trampoline is equivalent to this:
- *
- * if (obj) {
- *     if (obj->synchronisation) {
- *             if (obj->synchronisation->owner == 0) {
- *                     if (cmpxch (&obj->synchronisation->owner, TID, 0) == 0)
- *                             return;
- *             }
- *             if (obj->synchronisation->owner == TID) {
- *                     ++obj->synchronisation->nest;
- *                     return;
- *             }
- *     }
- * }
- * return full_monitor_enter ();
- *
- */
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
-       guint8 *code, *buf;
-       guint8 *jump_obj_null, *jump_sync_null, *jump_other_owner, *jump_cmpxchg_failed, *jump_tid, *jump_sync_thin_hash = NULL;
-       guint8 *jump_lock_taken_true = NULL;
-       int tramp_size;
-       int status_offset, nest_offset;
-       MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
-
-       g_assert (MONO_ARCH_MONITOR_OBJECT_REG == X86_EAX);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
-       g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG == X86_EDX);
-#else
-       g_assert (!is_v4);
-#endif
-
-       mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
-       status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
-       nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
-       tramp_size = NACL_SIZE (128, 192);
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       x86_push_reg (code, X86_EAX);
-       if (mono_thread_get_tls_offset () != -1) {
-               if (is_v4) {
-                       x86_test_membase_imm (code, X86_EDX, 0, 1);
-                       /* if *lock_taken is 1, jump to actual trampoline */
-                       jump_lock_taken_true = code;
-                       x86_branch8 (code, X86_CC_NZ, -1, 1);
-                       x86_push_reg (code, X86_EDX);
-               }
-               /* MonoObject* obj is in EAX */
-               /* is obj null? */
-               x86_test_reg_reg (code, X86_EAX, X86_EAX);
-               /* if yes, jump to actual trampoline */
-               jump_obj_null = code;
-               x86_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* load obj->synchronization to ECX */
-               x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 4);
-
-               if (mono_gc_is_moving ()) {
-                       /*if bit zero is set it's a thin hash*/
-                       /*FIXME use testb encoding*/
-                       x86_test_reg_imm (code, X86_ECX, 0x01);
-                       jump_sync_thin_hash = code;
-                       x86_branch8 (code, X86_CC_NE, -1, 1);
-
-                       /*clear bits used by the gc*/
-                       x86_alu_reg_imm (code, X86_AND, X86_ECX, ~0x3);
-               }
-
-               /* is synchronization null? */
-               x86_test_reg_reg (code, X86_ECX, X86_ECX);
-
-               /* if yes, jump to actual trampoline */
-               jump_sync_null = code;
-               x86_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* load MonoInternalThread* into EDX */
-               if (aot) {
-                       /* load_aotconst () puts the result into EAX */
-                       x86_mov_reg_reg (code, X86_EDX, X86_EAX, sizeof (mgreg_t));
-                       code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_TLS_OFFSET, GINT_TO_POINTER (TLS_KEY_THREAD));
-                       code = mono_x86_emit_tls_get_reg (code, X86_EAX, X86_EAX);
-                       x86_xchg_reg_reg (code, X86_EAX, X86_EDX, sizeof (mgreg_t));
-               } else {
-                       code = mono_x86_emit_tls_get (code, X86_EDX, mono_thread_get_tls_offset ());
-               }
-               /* load TID into EDX */
-               x86_mov_reg_membase (code, X86_EDX, X86_EDX, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
-
-               /* is synchronization->owner free */
-               x86_mov_reg_membase (code, X86_EAX, X86_ECX, status_offset, 4);
-               x86_test_reg_imm (code, X86_EAX, OWNER_MASK);
-               /* if not, jump to next case */
-               jump_tid = code;
-               x86_branch8 (code, X86_CC_NZ, -1, 1);
-
-               /* if yes, try a compare-exchange with the TID */
-               /* Form new status */
-               x86_alu_reg_reg (code, X86_OR, X86_EDX, X86_EAX);
-               /* compare and exchange */
-               x86_prefix (code, X86_LOCK_PREFIX);
-               x86_cmpxchg_membase_reg (code, X86_ECX, status_offset, X86_EDX);
-               /* if not successful, jump to actual trampoline */
-               jump_cmpxchg_failed = code;
-               x86_branch8 (code, X86_CC_NZ, -1, 1);
-               /* if successful, pop and return */
-               if (is_v4) {
-                       x86_pop_reg (code, X86_EDX);
-                       x86_mov_membase_imm (code, X86_EDX, 0, 1, 1);
-               }
-               x86_pop_reg (code, X86_EAX);
-               x86_ret (code);
-
-               /* next case: synchronization->owner is not null */
-               x86_patch (jump_tid, code);
-               /* is synchronization->owner == TID? */
-               x86_alu_reg_imm (code, X86_AND, X86_EAX, OWNER_MASK);
-               x86_alu_reg_reg (code, X86_CMP, X86_EAX, X86_EDX);
-               /* if not, jump to actual trampoline */
-               jump_other_owner = code;
-               x86_branch8 (code, X86_CC_NZ, -1, 1);
-               /* if yes, increment nest */
-               x86_inc_membase (code, X86_ECX, nest_offset);
-               if (is_v4) {
-                       x86_pop_reg (code, X86_EDX);
-                       x86_mov_membase_imm (code, X86_EDX, 0, 1, 1);
-               }
-               x86_pop_reg (code, X86_EAX);
-               /* return */
-               x86_ret (code);
-
-               /* obj is pushed, jump to the actual trampoline */
-               x86_patch (jump_obj_null, code);
-               if (jump_sync_thin_hash)
-                       x86_patch (jump_sync_thin_hash, code);
-               x86_patch (jump_sync_null, code);
-               x86_patch (jump_other_owner, code);
-               x86_patch (jump_cmpxchg_failed, code);
-
-               if (is_v4) {
-                       x86_pop_reg (code, X86_EDX);
-                       x86_patch (jump_lock_taken_true, code);
-               }
-       }
-
-       if (aot) {
-               /* We are calling the generic trampoline directly, the argument is pushed
-                * on the stack just like a specific trampoline.
-                */
-               if (is_v4)
-                       code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_enter_v4");
-               else
-                       code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_enter");
-               x86_jump_reg (code, X86_EAX);
-       } else {
-               if (is_v4)
-                       x86_jump_code (code, mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER_V4));
-               else
-                       x86_jump_code (code, mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER));
-       }
-
-       mono_arch_flush_icache (buf, code - buf);
-       g_assert (code - buf <= tramp_size);
-
-       nacl_global_codeman_validate (&buf, tramp_size, &code);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-
-       if (is_v4)
-               *info = mono_tramp_info_create ("monitor_enter_v4_trampoline", buf, code - buf, ji, unwind_ops);
-       else
-               *info = mono_tramp_info_create ("monitor_enter_trampoline", buf, code - buf, ji, unwind_ops);
-
-       return buf;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
-       guint8 *tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
-       guint8 *code, *buf;
-       guint8 *jump_obj_null, *jump_have_waiters, *jump_sync_null, *jump_not_owned, *jump_sync_thin_hash = NULL;
-       guint8 *jump_next, *jump_cmpxchg_failed;
-       int tramp_size;
-       int status_offset, nest_offset;
-       MonoJumpInfo *ji = NULL;
-       GSList *unwind_ops = NULL;
-
-       g_assert (MONO_ARCH_MONITOR_OBJECT_REG == X86_EAX);
-
-       mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
-       g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
-       status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
-       nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
-       tramp_size = NACL_SIZE (128, 192);
-
-       code = buf = mono_global_codeman_reserve (tramp_size);
-
-       x86_push_reg (code, X86_EAX);
-       if (mono_thread_get_tls_offset () != -1) {
-               /* MonoObject* obj is in EAX */
-               /* is obj null? */
-               x86_test_reg_reg (code, X86_EAX, X86_EAX);
-               /* if yes, jump to actual trampoline */
-               jump_obj_null = code;
-               x86_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* load obj->synchronization to ECX */
-               x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 4);
-
-               if (mono_gc_is_moving ()) {
-                       /*if bit zero is set it's a thin hash*/
-                       /*FIXME use testb encoding*/
-                       x86_test_reg_imm (code, X86_ECX, 0x01);
-                       jump_sync_thin_hash = code;
-                       x86_branch8 (code, X86_CC_NE, -1, 1);
-
-                       /*clear bits used by the gc*/
-                       x86_alu_reg_imm (code, X86_AND, X86_ECX, ~0x3);
-               }
-
-               /* is synchronization null? */
-               x86_test_reg_reg (code, X86_ECX, X86_ECX);
-               /* if yes, jump to actual trampoline */
-               jump_sync_null = code;
-               x86_branch8 (code, X86_CC_Z, -1, 1);
-
-               /* next case: synchronization is not null */
-               /* load MonoInternalThread* into EDX */
-               if (aot) {
-                       /* load_aotconst () puts the result into EAX */
-                       x86_mov_reg_reg (code, X86_EDX, X86_EAX, sizeof (mgreg_t));
-                       code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_TLS_OFFSET, GINT_TO_POINTER (TLS_KEY_THREAD));
-                       code = mono_x86_emit_tls_get_reg (code, X86_EAX, X86_EAX);
-                       x86_xchg_reg_reg (code, X86_EAX, X86_EDX, sizeof (mgreg_t));
-               } else {
-                       code = mono_x86_emit_tls_get (code, X86_EDX, mono_thread_get_tls_offset ());
-               }
-               /* load TID into EDX */
-               x86_mov_reg_membase (code, X86_EDX, X86_EDX, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
-               /* is synchronization->owner == TID */
-               x86_mov_reg_membase (code, X86_EAX, X86_ECX, status_offset, 4);
-               x86_alu_reg_reg (code, X86_XOR, X86_EDX, X86_EAX);
-               x86_test_reg_imm (code, X86_EDX, OWNER_MASK);
-               /* if no, jump to actual trampoline */
-               jump_not_owned = code;
-               x86_branch8 (code, X86_CC_NZ, -1, 1);
-
-               /* next case: synchronization->owner == TID */
-               /* is synchronization->nest == 1 */
-               x86_alu_membase_imm (code, X86_CMP, X86_ECX, nest_offset, 1);
-               /* if not, jump to next case */
-               jump_next = code;
-               x86_branch8 (code, X86_CC_NZ, -1, 1);
-               /* if yes, is synchronization->entry_count greater than zero? */
-               x86_test_reg_imm (code, X86_EAX, ENTRY_COUNT_WAITERS);
-               /* if yes, jump to actual trampoline */
-               jump_have_waiters = code;
-               x86_branch8 (code, X86_CC_NZ, -1 , 1);
-               /* if not, try to set synchronization->owner to null and return */
-               x86_mov_reg_reg (code, X86_EDX, X86_EAX, 4);
-               x86_alu_reg_imm (code, X86_AND, X86_EDX, ENTRY_COUNT_MASK); 
-               /* compare and exchange */
-               x86_prefix (code, X86_LOCK_PREFIX);
-               /* EAX contains the previous status */
-               x86_cmpxchg_membase_reg (code, X86_ECX, status_offset, X86_EDX);
-               /* if not successful, jump to actual trampoline */
-               jump_cmpxchg_failed = code;
-               x86_branch8 (code, X86_CC_NZ, -1, 1);
-
-               x86_pop_reg (code, X86_EAX);
-               x86_ret (code);
-
-               /* next case: synchronization->nest is not 1 */
-               x86_patch (jump_next, code);
-               /* decrease synchronization->nest and return */
-               x86_dec_membase (code, X86_ECX, nest_offset);
-               x86_pop_reg (code, X86_EAX);
-               x86_ret (code);
-
-               /* push obj and jump to the actual trampoline */
-               x86_patch (jump_obj_null, code);
-               if (jump_sync_thin_hash)
-                       x86_patch (jump_sync_thin_hash, code);
-               x86_patch (jump_have_waiters, code);
-               x86_patch (jump_cmpxchg_failed, code);
-               x86_patch (jump_not_owned, code);
-               x86_patch (jump_sync_null, code);
-       }
-
-       /* obj is pushed, jump to the actual trampoline */
-       if (aot) {
-               code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_exit");
-               x86_jump_reg (code, X86_EAX);
-       } else {
-               x86_jump_code (code, tramp);
-       }
-
-       nacl_global_codeman_validate (&buf, tramp_size, &code);
-
-       mono_arch_flush_icache (buf, code - buf);
-       g_assert (code - buf <= tramp_size);
-       mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-
-       *info = mono_tramp_info_create ("monitor_exit_trampoline", buf, code - buf, ji, unwind_ops);
-
-       return buf;
-}
-
-#else
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
-
-#endif
-
 void
 mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
 {
@@ -973,12 +663,15 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
        guint8 *code, *buf;
        int tramp_size = 64;
        MonoJumpInfo *ji = NULL;
+       int cfa_offset;
        GSList *unwind_ops = NULL;
 
        g_assert (!aot);
 
        code = buf = mono_global_codeman_reserve (tramp_size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+       cfa_offset = sizeof (mgreg_t);
        /*
        This trampoline restore the call chain of the handler block then jumps into the code that deals with it.
        */
@@ -997,10 +690,18 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
        /* Simulate a call */
        /*Fix stack alignment*/
        x86_alu_reg_imm (code, X86_SUB, X86_ESP, 0x4);
+       cfa_offset += sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+
        /* This is the address the trampoline will return to */
        x86_push_reg (code, X86_EAX);
+       cfa_offset += sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+
        /* Dummy trampoline argument, since we call the generic trampoline directly */
        x86_push_imm (code, 0);
+       cfa_offset += sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
        x86_jump_code (code, tramp);
 
        nacl_global_codeman_validate (&buf, tramp_size, &code);
@@ -1043,11 +744,15 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint
 {
        guint8 *code, *start;
        int buf_len;
+       GSList *unwind_ops;
+
 
        buf_len = 10;
 
        start = code = mono_domain_code_reserve (domain, buf_len);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        x86_mov_reg_imm (code, X86_EAX, arg);
        x86_jump_code (code, addr);
        g_assert ((code - start) <= buf_len);
@@ -1056,9 +761,111 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }
 
+/*
+ * mono_arch_create_sdb_trampoline:
+ *
+ *   Return a trampoline which captures the current context, passes it to
+ * debugger_agent_single_step_from_context ()/debugger_agent_breakpoint_from_context (),
+ * then restores the (potentially changed) context.
+ */
+guint8*
+mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot)
+{
+       int tramp_size = 256;
+       int framesize, ctx_offset, cfa_offset;
+       guint8 *code, *buf;
+       GSList *unwind_ops = NULL;
+       MonoJumpInfo *ji = NULL;
+
+       code = buf = mono_global_codeman_reserve (tramp_size);
+
+       framesize = 0;
+
+       /* Argument area */
+       framesize += sizeof (mgreg_t);
+
+       ctx_offset = framesize;
+       framesize += sizeof (MonoContext);
+
+       framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT);
+
+       // CFA = sp + 4
+       cfa_offset = 4;
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, 4);
+       // IP saved at CFA - 4
+       mono_add_unwind_op_offset (unwind_ops, code, buf, X86_NREG, -cfa_offset);
+
+       x86_push_reg (code, X86_EBP);
+       cfa_offset += sizeof(mgreg_t);
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+       mono_add_unwind_op_offset (unwind_ops, code, buf, X86_EBP, - cfa_offset);
+
+       x86_mov_reg_reg (code, X86_EBP, X86_ESP, sizeof(mgreg_t));
+       mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, X86_EBP);
+       /* The + 8 makes the stack aligned */
+       x86_alu_reg_imm (code, X86_SUB, X86_ESP, framesize + 8);
+
+       /* Initialize a MonoContext structure on the stack */
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eax), X86_EAX, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebx), X86_EBX, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ecx), X86_ECX, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edx), X86_EDX, sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_EAX, X86_EBP, 0, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebp), X86_EAX, sizeof (mgreg_t));
+       x86_mov_reg_reg (code, X86_EAX, X86_EBP, sizeof (mgreg_t));
+       x86_alu_reg_imm (code, X86_ADD, X86_EAX, cfa_offset);
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, esp), X86_ESP, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, esi), X86_ESI, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edi), X86_EDI, sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_EAX, X86_EBP, 4, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eip), X86_EAX, sizeof (mgreg_t));
+
+       /* Call the single step/breakpoint function in sdb */
+       x86_lea_membase (code, X86_EAX, X86_ESP, ctx_offset);
+       x86_mov_membase_reg (code, X86_ESP, 0, X86_EAX, sizeof (mgreg_t));
+
+       if (aot) {
+               x86_breakpoint (code);
+       } else {
+               if (single_step)
+                       x86_call_code (code, debugger_agent_single_step_from_context);
+               else
+                       x86_call_code (code, debugger_agent_breakpoint_from_context);
+       }
+
+       /* Restore registers from ctx */
+       /* Overwrite the saved ebp */
+       x86_mov_reg_membase (code, X86_EAX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebp), sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_EBP, 0, X86_EAX, sizeof (mgreg_t));
+       /* Overwrite saved eip */
+       x86_mov_reg_membase (code, X86_EAX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eip), sizeof (mgreg_t));
+       x86_mov_membase_reg (code, X86_EBP, 4, X86_EAX, sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_EAX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eax), sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_EBX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebx), sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_ECX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ecx), sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_EDX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edx), sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_ESI, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, esi), sizeof (mgreg_t));
+       x86_mov_reg_membase (code, X86_EDI, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edi), sizeof (mgreg_t));
+
+       x86_leave (code);
+       cfa_offset -= sizeof (mgreg_t);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset);
+       x86_ret (code);
+
+       mono_arch_flush_icache (code, code - buf);
+       g_assert (code - buf <= tramp_size);
+
+       const char *tramp_name = single_step ? "sdb_single_step_trampoline" : "sdb_breakpoint_trampoline";
+       *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops);
+
+       return buf;
+}
+
 #if defined(ENABLE_GSHAREDVT)
 
 #include "../../../mono-extensions/mono/mini/tramp-x86-gsharedvt.c"
index 52b292ef0808a7d2b96920791df7d7584af5f6f7..1fbd5c9f63bbfed5c3b6bf580c31fb63a4770743 100644 (file)
@@ -338,13 +338,15 @@ mono_print_unwind_info (guint8 *unwind_info, int unwind_info_len)
 }
 
 /*
- * mono_unwind_ops_encode:
+ * mono_unwind_ops_encode_full:
  *
  *   Encode the unwind ops in UNWIND_OPS into the compact DWARF encoding.
  * Return a pointer to malloc'ed memory.
+ * If ENABLE_EXTENSIONS is FALSE, avoid encoding the mono extension
+ * opcode (DW_CFA_mono_advance_loc).
  */
 guint8*
-mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
+mono_unwind_ops_encode_full (GSList *unwind_ops, guint32 *out_len, gboolean enable_extensions)
 {
        GSList *l;
        MonoUnwindOp *op;
@@ -430,6 +432,8 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
                        *p ++ = op->op;
                        break;
                case DW_CFA_mono_advance_loc:
+                       if (!enable_extensions)
+                               break;
                        /* Only one location is supported */
                        g_assert (op->val == 0);
                        *p ++ = op->op;
@@ -447,6 +451,12 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
        return res;
 }
 
+guint8*
+mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
+{
+       return mono_unwind_ops_encode_full (unwind_ops, out_len, TRUE);
+}
+
 #if 0
 #define UNW_DEBUG(stmt) do { stmt; } while (0)
 #else
@@ -1164,7 +1174,7 @@ mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8
 GSList*
 mono_unwind_get_cie_program (void)
 {
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_POWERPC)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_POWERPC) || defined(TARGET_ARM)
        return mono_arch_get_cie_program ();
 #else
        return NULL;
index 9924906bd90e625e238e6ca9ad03893a171431f1..0df2d3cd1af74d33f445fa11a8beaef0d820a95e 100644 (file)
@@ -1845,6 +1845,7 @@ typedef struct {
        uint64_t live;
        uint64_t max_live;
        TraceDesc traces;
+       TraceDesc destroy_traces;
 } HandleInfo;
 static HandleInfo handle_info [4];
 
@@ -1991,12 +1992,18 @@ tracked_creation (uintptr_t obj, ClassDesc *cd, uint64_t size, BackTrace *bt, ui
 }
 
 static void
-track_handle (uintptr_t obj, int htype, uint32_t handle)
+track_handle (uintptr_t obj, int htype, uint32_t handle, BackTrace *bt, uint64_t timestamp)
 {
        int i;
        for (i = 0; i < num_tracked_objects; ++i) {
-               if (tracked_objects [i] == obj)
-                       fprintf (outfile, "Object %p referenced from handle %u\n", (void*)obj, handle);
+               if (tracked_objects [i] != obj)
+                       continue;
+               fprintf (outfile, "Object %p referenced from handle %u at %.3f secs.\n", (void*)obj, handle, (timestamp - startup_time) / 1000000000.0);
+               if (bt && bt->count) {
+                       int k;
+                       for (k = 0; k < bt->count; ++k)
+                               fprintf (outfile, "\t%s\n", bt->methods [k]->name);
+               }
        }
 }
 
@@ -2274,31 +2281,72 @@ decode_buffer (ProfContext *ctx)
                                                fprintf (outfile, "moved obj %p to %p\n", (void*)OBJ_ADDR (obj1diff), (void*)OBJ_ADDR (obj2diff));
                                        }
                                }
-                       } else if (subtype == TYPE_GC_HANDLE_CREATED) {
+                       } else if (subtype == TYPE_GC_HANDLE_CREATED || subtype == TYPE_GC_HANDLE_CREATED_BT) {
+                               int has_bt = subtype == TYPE_GC_HANDLE_CREATED_BT;
+                               int num_bt = 0;
+                               MethodDesc *sframes [8];
+                               MethodDesc **frames = sframes;
                                int htype = decode_uleb128 (p, &p);
                                uint32_t handle = decode_uleb128 (p, &p);
                                intptr_t objdiff = decode_sleb128 (p, &p);
+                               if (has_bt) {
+                                       num_bt = 8;
+                                       frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+                                       if (!frames) {
+                                               fprintf (outfile, "Cannot load backtrace\n");
+                                               return 0;
+                                       }
+                               }
                                if (htype > 3)
                                        return 0;
-                               handle_info [htype].created++;
-                               handle_info [htype].live++;
-                               add_trace_thread (thread, &handle_info [htype].traces, 1);
-                               /* FIXME: we don't take into account timing here */
-                               if (handle_info [htype].live > handle_info [htype].max_live)
-                                       handle_info [htype].max_live = handle_info [htype].live;
-                               if (num_tracked_objects)
-                                       track_handle (OBJ_ADDR (objdiff), htype, handle);
+                               if ((thread_filter && thread_filter == thread->thread_id) || (time_base >= time_from && time_base < time_to)) {
+                                       handle_info [htype].created++;
+                                       handle_info [htype].live++;
+                                       if (handle_info [htype].live > handle_info [htype].max_live)
+                                               handle_info [htype].max_live = handle_info [htype].live;
+                                       BackTrace *bt;
+                                       if (has_bt)
+                                               bt = add_trace_methods (frames, num_bt, &handle_info [htype].traces, 1);
+                                       else
+                                               bt = add_trace_thread (thread, &handle_info [htype].traces, 1);
+                                       if (num_tracked_objects)
+                                               track_handle (OBJ_ADDR (objdiff), htype, handle, bt, time_base);
+                               }
                                if (debug)
                                        fprintf (outfile, "handle (%s) %u created for object %p\n", get_handle_name (htype), handle, (void*)OBJ_ADDR (objdiff));
-                       } else if (subtype == TYPE_GC_HANDLE_DESTROYED) {
+                               if (frames != sframes)
+                                       free (frames);
+                       } else if (subtype == TYPE_GC_HANDLE_DESTROYED || subtype == TYPE_GC_HANDLE_DESTROYED_BT) {
+                               int has_bt = subtype == TYPE_GC_HANDLE_DESTROYED_BT;
+                               int num_bt = 0;
+                               MethodDesc *sframes [8];
+                               MethodDesc **frames = sframes;
                                int htype = decode_uleb128 (p, &p);
                                uint32_t handle = decode_uleb128 (p, &p);
+                               if (has_bt) {
+                                       num_bt = 8;
+                                       frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+                                       if (!frames) {
+                                               fprintf (outfile, "Cannot load backtrace\n");
+                                               return 0;
+                                       }
+                               }
                                if (htype > 3)
                                        return 0;
-                               handle_info [htype].destroyed ++;
-                               handle_info [htype].live--;
+                               if ((thread_filter && thread_filter == thread->thread_id) || (time_base >= time_from && time_base < time_to)) {
+                                       handle_info [htype].destroyed ++;
+                                       handle_info [htype].live--;
+                                       BackTrace *bt;
+                                       if (has_bt)
+                                               bt = add_trace_methods (frames, num_bt, &handle_info [htype].destroy_traces, 1);
+                                       else
+                                               bt = add_trace_thread (thread, &handle_info [htype].destroy_traces, 1);
+                                       /* TODO: track_handle_free () - would need to record and keep track of the associated object address... */
+                               }
                                if (debug)
                                        fprintf (outfile, "handle (%s) %u destroyed\n", get_handle_name (htype), handle);
+                               if (frames != sframes)
+                                       free (frames);
                        }
                        break;
                }
@@ -3178,6 +3226,7 @@ dump_gcs (void)
                        (unsigned long long) (handle_info [i].destroyed),
                        (unsigned long long) (handle_info [i].max_live));
                dump_traces (&handle_info [i].traces, "created");
+               dump_traces (&handle_info [i].destroy_traces, "destroyed");
        }
 }
 
diff --git a/mono/profiler/mono-codeanalyst.c b/mono/profiler/mono-codeanalyst.c
deleted file mode 100644 (file)
index a6d13a0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * mono-codeanalyst.c: AMD CodeAnalyst profiler
- *
- * Author:
- *   Jonathan Chambers (joncham@gmail.com)
- *
- * (C) 2011 Jonathan Chambers
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <mono/metadata/profiler.h>
-#include <mono/metadata/tokentype.h>
-#include <mono/metadata/tabledefs.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/assembly.h>
-#include <string.h>
-#include <glib.h>
-
-#define bool char
-
-#include "CAJITNTFLib.h"
-
-/* called at the end of the program */
-static void
-codeanalyst_shutdown (MonoProfiler *prof)
-{
-       CAJIT_CompleteJITLog ();
-}
-
-static void
-method_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) {
-       if (result == MONO_PROFILE_OK) {
-               gunichar2* name_utf16;
-               MonoClass *klass = mono_method_get_class (method);
-               char *signature = mono_signature_get_desc (mono_method_signature (method), TRUE);
-               char *name = g_strdup_printf ("%s.%s.%s (%s)", mono_class_get_namespace (klass), mono_class_get_name (klass), mono_method_get_name (method), signature);
-               gpointer code_start = mono_jit_info_get_code_start (jinfo);
-               int code_size = mono_jit_info_get_code_size (jinfo);
-               
-               name_utf16 = g_utf8_to_utf16 (name, strlen (name), NULL, NULL, NULL);
-               
-               CAJIT_LogJITCode ((uintptr_t)code_start, code_size, (wchar_t*)name_utf16);
-               
-               g_free (signature);
-               g_free (name);
-               g_free (name_utf16);
-       }
-}
-
-void
-mono_profiler_startup (const char *desc);
-
-/* the entry point */
-void
-mono_profiler_startup (const char *desc)
-{
-       CAJIT_Initialize ();
-
-       mono_profiler_install (NULL, codeanalyst_shutdown);
-       mono_profiler_install_jit_end (method_jit_result);
-       mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION);
-}
-
-
index 59d84d189f210eb67a2db8c2d0856cd7d66bcf03..7e2fe8d5af06259c940ffdc7fb1e1b1250b4d50a 100644 (file)
@@ -198,8 +198,8 @@ typedef struct _LogBuffer LogBuffer;
  *
  * type GC format:
  * type: TYPE_GC
- * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED,
- * TYPE_GC_HANDLE_DESTROYED
+ * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED[_BT],
+ * TYPE_GC_HANDLE_DESTROYED[_BT]
  * [time diff: uleb128] nanoseconds since last timing
  * if exinfo == TYPE_GC_RESIZE
  *     [heap_size: uleb128] new heap size
@@ -211,15 +211,17 @@ typedef struct _LogBuffer LogBuffer;
  *     [objaddr: sleb128]+ num_objects object pointer differences from obj_base
  *     num is always an even number: the even items are the old
  *     addresses, the odd numbers are the respective new object addresses
- * if exinfo == TYPE_GC_HANDLE_CREATED
+ * if exinfo == TYPE_GC_HANDLE_CREATED[_BT]
  *     [handle_type: uleb128] GC handle type (System.Runtime.InteropServices.GCHandleType)
  *     upper bits reserved as flags
  *     [handle: uleb128] GC handle value
  *     [objaddr: sleb128] object pointer differences from obj_base
- * if exinfo == TYPE_GC_HANDLE_DESTROYED
+ *     If exinfo == TYPE_GC_HANDLE_CREATED_BT, a backtrace follows.
+ * if exinfo == TYPE_GC_HANDLE_DESTROYED[_BT]
  *     [handle_type: uleb128] GC handle type (System.Runtime.InteropServices.GCHandleType)
  *     upper bits reserved as flags
  *     [handle: uleb128] GC handle value
+ *     If exinfo == TYPE_GC_HANDLE_DESTROYED_BT, a backtrace follows.
  *
  * type metadata format:
  * type: TYPE_METADATA
@@ -230,21 +232,23 @@ typedef struct _LogBuffer LogBuffer;
  * [pointer: sleb128] pointer of the metadata type depending on mtype
  * if mtype == TYPE_CLASS
  *     [image: sleb128] MonoImage* as a pointer difference from ptr_base
- *  [flags: uleb128] must be 0
+ *     [flags: uleb128] must be 0
  *     [name: string] full class name
  * if mtype == TYPE_IMAGE
- *  [flags: uleb128] must be 0
+ *     [flags: uleb128] must be 0
  *     [name: string] image file name
  * if mtype == TYPE_ASSEMBLY
- *  [flags: uleb128] must be 0
+ *     [flags: uleb128] must be 0
  *     [name: string] assembly name
  * if mtype == TYPE_DOMAIN
- *  [flags: uleb128] must be 0
+ *     [flags: uleb128] must be 0
  * if mtype == TYPE_DOMAIN && exinfo == 0
  *     [name: string] domain friendly name
  * if mtype == TYPE_CONTEXT
+ *     [flags: uleb128] must be 0
  *     [domain: sleb128] domain id as pointer
  * if mtype == TYPE_THREAD && (format_version < 11 || (format_version > 10 && exinfo == 0))
+ *     [flags: uleb128] must be 0
  *     [name: string] thread name
  *
  * type method format:
@@ -1169,7 +1173,13 @@ gc_roots (MonoProfiler *prof, int num, void **objects, int *root_types, uintptr_
 static void
 gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj)
 {
+       int do_bt = nocalls && InterlockedRead (&runtime_inited) && !notraces;
        uint64_t now;
+       FrameData data;
+
+       if (do_bt)
+               collect_bt (&data);
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                LEB128_SIZE /* time */ +
@@ -1177,21 +1187,36 @@ gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *o
                LEB128_SIZE /* handle */ +
                (op == MONO_PROFILER_GC_HANDLE_CREATED ? (
                        LEB128_SIZE /* obj */
+               ) : 0) +
+               (do_bt ? (
+                       LEB128_SIZE /* flags */ +
+                       LEB128_SIZE /* count */ +
+                       data.count * (
+                               LEB128_SIZE /* method */
+                       )
                ) : 0)
        );
+
        now = current_time ();
        ENTER_LOG (logbuffer, "gchandle");
+
        if (op == MONO_PROFILER_GC_HANDLE_CREATED)
-               emit_byte (logbuffer, TYPE_GC_HANDLE_CREATED | TYPE_GC);
+               emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_CREATED_BT : TYPE_GC_HANDLE_CREATED) | TYPE_GC);
        else if (op == MONO_PROFILER_GC_HANDLE_DESTROYED)
-               emit_byte (logbuffer, TYPE_GC_HANDLE_DESTROYED | TYPE_GC);
+               emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_DESTROYED_BT : TYPE_GC_HANDLE_DESTROYED) | TYPE_GC);
        else
-               return;
+               g_assert_not_reached ();
+
        emit_time (logbuffer, now);
        emit_value (logbuffer, type);
        emit_value (logbuffer, handle);
+
        if (op == MONO_PROFILER_GC_HANDLE_CREATED)
                emit_obj (logbuffer, obj);
+
+       if (do_bt)
+               emit_bt (prof, logbuffer, &data);
+
        EXIT_LOG (logbuffer);
        process_requests (prof);
 }
@@ -3168,20 +3193,15 @@ counters_and_perfcounters_sample (MonoProfiler *prof)
 }
 
 #define COVERAGE_DEBUG(x) if (debug_coverage) {x}
+static mono_mutex_t coverage_mutex;
 static MonoConcurrentHashTable *coverage_methods = NULL;
-static mono_mutex_t coverage_methods_mutex;
 static MonoConcurrentHashTable *coverage_assemblies = NULL;
-static mono_mutex_t coverage_assemblies_mutex;
 static MonoConcurrentHashTable *coverage_classes = NULL;
-static mono_mutex_t coverage_classes_mutex;
+
 static MonoConcurrentHashTable *filtered_classes = NULL;
-static mono_mutex_t filtered_classes_mutex;
 static MonoConcurrentHashTable *entered_methods = NULL;
-static mono_mutex_t entered_methods_mutex;
 static MonoConcurrentHashTable *image_to_methods = NULL;
-static mono_mutex_t image_to_methods_mutex;
 static MonoConcurrentHashTable *suppressed_assemblies = NULL;
-static mono_mutex_t suppressed_assemblies_mutex;
 static gboolean coverage_initialized = FALSE;
 
 static GPtrArray *coverage_data = NULL;
@@ -3499,9 +3519,11 @@ dump_coverage (MonoProfiler *prof)
        COVERAGE_DEBUG(fprintf (stderr, "Coverage: Started dump\n");)
        method_id = 0;
 
+       mono_mutex_lock (&coverage_mutex);
        mono_conc_hashtable_foreach (coverage_assemblies, build_assembly_buffer, prof);
        mono_conc_hashtable_foreach (coverage_classes, build_class_buffer, prof);
        mono_conc_hashtable_foreach (coverage_methods, build_method_buffer, prof);
+       mono_mutex_unlock (&coverage_mutex);
 
        COVERAGE_DEBUG(fprintf (stderr, "Coverage: Finished dump\n");)
 }
@@ -3521,7 +3543,9 @@ process_method_enter_coverage (MonoProfiler *prof, MonoMethod *method)
        if (mono_conc_hashtable_lookup (suppressed_assemblies, (gpointer) mono_image_get_name (image)))
                return;
 
+       mono_mutex_lock (&coverage_mutex);
        mono_conc_hashtable_insert (entered_methods, method, method);
+       mono_mutex_unlock (&coverage_mutex);
 }
 
 static MonoLockFreeQueueNode *
@@ -3608,7 +3632,9 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
                if (has_positive && !found) {
                        COVERAGE_DEBUG(fprintf (stderr, "   Positive match was not found\n");)
 
+                       mono_mutex_lock (&coverage_mutex);
                        mono_conc_hashtable_insert (filtered_classes, klass, klass);
+                       mono_mutex_unlock (&coverage_mutex);
                        g_free (fqn);
                        g_free (classname);
 
@@ -3628,7 +3654,9 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
                        if (strstr (fqn, filter) != NULL) {
                                COVERAGE_DEBUG(fprintf (stderr, "matched\n");)
 
+                               mono_mutex_lock (&coverage_mutex);
                                mono_conc_hashtable_insert (filtered_classes, klass, klass);
+                               mono_mutex_unlock (&coverage_mutex);
                                g_free (fqn);
                                g_free (classname);
 
@@ -3649,15 +3677,19 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
 
        assembly = mono_image_get_assembly (image);
 
+       mono_mutex_lock (&coverage_mutex);
        mono_conc_hashtable_insert (coverage_methods, method, method);
        mono_conc_hashtable_insert (coverage_assemblies, assembly, assembly);
+       mono_mutex_unlock (&coverage_mutex);
 
        image_methods = mono_conc_hashtable_lookup (image_to_methods, image);
 
        if (image_methods == NULL) {
                image_methods = g_malloc (sizeof (MonoLockFreeQueue));
                mono_lock_free_queue_init (image_methods);
+               mono_mutex_lock (&coverage_mutex);
                mono_conc_hashtable_insert (image_to_methods, image, image_methods);
+               mono_mutex_unlock (&coverage_mutex);
        }
 
        node = create_method_node (method);
@@ -3668,7 +3700,9 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method)
        if (class_methods == NULL) {
                class_methods = g_malloc (sizeof (MonoLockFreeQueue));
                mono_lock_free_queue_init (class_methods);
+               mono_mutex_lock (&coverage_mutex);
                mono_conc_hashtable_insert (coverage_classes, klass, class_methods);
+               mono_mutex_unlock (&coverage_mutex);
        }
 
        node = create_method_node (method);
@@ -3741,8 +3775,7 @@ init_suppressed_assemblies (void)
        char *line;
        FILE *sa_file;
 
-       mono_mutex_init (&suppressed_assemblies_mutex);
-       suppressed_assemblies = mono_conc_hashtable_new (&suppressed_assemblies_mutex, g_str_hash, g_str_equal);
+       suppressed_assemblies = mono_conc_hashtable_new (g_str_hash, g_str_equal);
        sa_file = fopen (SUPPRESSION_DIR "/mono-profiler-log.suppression", "r");
        if (sa_file == NULL)
                return;
@@ -3755,26 +3788,13 @@ init_suppressed_assemblies (void)
 
        while ((line = get_next_line (content, &content))) {
                line = g_strchomp (g_strchug (line));
+               /* No locking needed as we're doing initialization */
                mono_conc_hashtable_insert (suppressed_assemblies, line, line);
        }
 
        fclose (sa_file);
 }
 
-static MonoConcurrentHashTable *
-init_hashtable (mono_mutex_t *mutex)
-{
-       mono_mutex_init (mutex);
-       return mono_conc_hashtable_new (mutex, NULL, NULL);
-}
-
-static void
-destroy_hashtable (MonoConcurrentHashTable *hashtable, mono_mutex_t *mutex)
-{
-       mono_conc_hashtable_destroy (hashtable);
-       mono_mutex_destroy (mutex);
-}
-
 #endif /* DISABLE_HELPER_THREAD */
 
 static void
@@ -3785,12 +3805,13 @@ coverage_init (MonoProfiler *prof)
 
        COVERAGE_DEBUG(fprintf (stderr, "Coverage initialized\n");)
 
-       coverage_methods = init_hashtable (&coverage_methods_mutex);
-       coverage_assemblies = init_hashtable (&coverage_assemblies_mutex);
-       coverage_classes = init_hashtable (&coverage_classes_mutex);
-       filtered_classes = init_hashtable (&filtered_classes_mutex);
-       entered_methods = init_hashtable (&entered_methods_mutex);
-       image_to_methods = init_hashtable (&image_to_methods_mutex);
+       mono_mutex_init (&coverage_mutex);
+       coverage_methods = mono_conc_hashtable_new (NULL, NULL);
+       coverage_assemblies = mono_conc_hashtable_new (NULL, NULL);
+       coverage_classes = mono_conc_hashtable_new (NULL, NULL);
+       filtered_classes = mono_conc_hashtable_new (NULL, NULL);
+       entered_methods = mono_conc_hashtable_new (NULL, NULL);
+       image_to_methods = mono_conc_hashtable_new (NULL, NULL);
        init_suppressed_assemblies ();
 
        coverage_initialized = TRUE;
@@ -3842,16 +3863,19 @@ log_shutdown (MonoProfiler *prof)
        else
                fclose (prof->file);
 
-       destroy_hashtable (prof->method_table, &prof->method_table_mutex);
+       mono_conc_hashtable_destroy (prof->method_table);
+       mono_mutex_destroy (&prof->method_table_mutex);
 
        if (coverage_initialized) {
-               destroy_hashtable (coverage_methods, &coverage_methods_mutex);
-               destroy_hashtable (coverage_assemblies, &coverage_assemblies_mutex);
-               destroy_hashtable (coverage_classes, &coverage_classes_mutex);
-               destroy_hashtable (filtered_classes, &filtered_classes_mutex);
-               destroy_hashtable (entered_methods, &entered_methods_mutex);
-               destroy_hashtable (image_to_methods, &image_to_methods_mutex);
-               destroy_hashtable (suppressed_assemblies, &suppressed_assemblies_mutex);
+               mono_conc_hashtable_destroy (coverage_methods);
+               mono_conc_hashtable_destroy (coverage_assemblies);
+               mono_conc_hashtable_destroy (coverage_classes);
+               mono_conc_hashtable_destroy (filtered_classes);
+
+               mono_conc_hashtable_destroy (entered_methods);
+               mono_conc_hashtable_destroy (image_to_methods);
+               mono_conc_hashtable_destroy (suppressed_assemblies);
+               mono_mutex_destroy (&coverage_mutex);
        }
 
        free (prof);
@@ -4149,7 +4173,9 @@ writer_thread (void *arg)
                                 * method lists will just be empty for the rest of the
                                 * app's lifetime.
                                 */
+                               mono_mutex_lock (&prof->method_table_mutex);
                                mono_conc_hashtable_insert (prof->method_table, info->method, info->method);
+                               mono_mutex_unlock (&prof->method_table_mutex);
 
                                char *name = mono_method_full_name (info->method, 1);
                                int nlen = strlen (name) + 1;
@@ -4299,7 +4325,7 @@ create_profiler (const char *filename, GPtrArray *filters)
 
        mono_lock_free_queue_init (&prof->writer_queue);
        mono_mutex_init (&prof->method_table_mutex);
-       prof->method_table = mono_conc_hashtable_new (&prof->method_table_mutex, NULL, NULL);
+       prof->method_table = mono_conc_hashtable_new (NULL, NULL);
 
        if (do_coverage)
                coverage_init (prof);
index a2c0fb25f17cef9802401ac28e635aca0780b642..8fc22e432828e6c7692723d70088411ff3284fad 100644 (file)
@@ -24,6 +24,7 @@
                    load/unload for contexts
                    load/unload/name for assemblies
                removed TYPE_LOAD_ERR flag (profiler never generated it, now removed from the format itself)
+               added TYPE_GC_HANDLE_{CREATED,DESTROYED}_BT
  */
 
 enum {
@@ -56,8 +57,10 @@ enum {
        TYPE_GC_EVENT  = 1 << 4,
        TYPE_GC_RESIZE = 2 << 4,
        TYPE_GC_MOVE   = 3 << 4,
-       TYPE_GC_HANDLE_CREATED   = 4 << 4,
-       TYPE_GC_HANDLE_DESTROYED = 5 << 4,
+       TYPE_GC_HANDLE_CREATED      = 4 << 4,
+       TYPE_GC_HANDLE_DESTROYED    = 5 << 4,
+       TYPE_GC_HANDLE_CREATED_BT   = 6 << 4,
+       TYPE_GC_HANDLE_DESTROYED_BT = 7 << 4,
        /* extended type for TYPE_METHOD */
        TYPE_LEAVE     = 1 << 4,
        TYPE_ENTER     = 2 << 4,
index 410ba6aab0a0435b0e61a4f1cdded22bc4e2ad62..5e349f8416ee22539b4e1eee99f7e4599765cbd8 100644 (file)
@@ -88,8 +88,8 @@
        } while (0)
 
 /* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
-   archs is 64k.  */
-#if defined(TARGET_POWERPC64) && _CALL_ELF == 2
+   architectures is 64k.  */
+#if defined(TARGET_POWERPC64)
 #define ARCH_MIN_MS_BLOCK_SIZE (64*1024)
 #define ARCH_MIN_MS_BLOCK_SIZE_SHIFT   16
 #endif
index 4b1a1ac16169849b72bd9bc8b630e45592caa29f..f2227aa9f7282017e211ac0c9cc27f206420ef84 100644 (file)
@@ -822,7 +822,7 @@ sgen_conservatively_pin_objects_from (void **start, void **end, void *start_nurs
 {
        int count = 0;
 
-#ifdef VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE
+#if defined(VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE) && !defined(_WIN64)
        VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE (start, (char*)end - (char*)start);
 #endif
 
index 49fb4c1fac132347f01575b8c0130dfaefe5b8aa..103a7fe5d9ffddf00da9a06cb2cf9bd41684293b 100644 (file)
@@ -98,7 +98,12 @@ struct _GCMemSection {
 
 extern LOCK_DECLARE (sgen_interruption_mutex);
 
-#define LOCK_INTERRUPTION mono_mutex_lock (&sgen_interruption_mutex)
+#define LOCK_INTERRUPTION do { \
+       MONO_TRY_BLOCKING       \
+       mono_mutex_lock (&sgen_interruption_mutex);     \
+       MONO_FINISH_TRY_BLOCKING        \
+} while (0)
+
 #define UNLOCK_INTERRUPTION mono_mutex_unlock (&sgen_interruption_mutex)
 
 /* FIXME: Use InterlockedAdd & InterlockedAdd64 to reduce the CAS cost. */
index 70cf34fb8a9a6e26828a8453f0af92181c063d5b..ea1ba4692ea64a635a639476aba2be9c22ba16d6 100644 (file)
@@ -92,6 +92,12 @@ static char *los_segment = NULL;
 static int los_segment_index = 0;
 #endif
 
+mword
+sgen_los_object_size (LOSObject *obj)
+{
+       return obj->size & ~1L;
+}
+
 #ifdef LOS_CONSISTENCY_CHECK
 static void
 los_consistency_check (void)
@@ -102,12 +108,13 @@ los_consistency_check (void)
        mword memory_usage = 0;
 
        for (obj = los_object_list; obj; obj = obj->next) {
-               char *end = obj->data + obj->size;
+               mword obj_size = sgen_los_object_size (obj);
+               char *end = obj->data + obj_size;
                int start_index, num_chunks;
 
-               memory_usage += obj->size;
+               memory_usage += obj_size;
 
-               if (obj->size > LOS_SECTION_OBJECT_LIMIT)
+               if (obj_size > LOS_SECTION_OBJECT_LIMIT)
                        continue;
 
                section = LOS_SECTION_FOR_OBJ (obj);
@@ -115,7 +122,7 @@ los_consistency_check (void)
                g_assert (end <= (char*)section + LOS_SECTION_SIZE);
 
                start_index = LOS_CHUNK_INDEX (obj, section);
-               num_chunks = (obj->size + sizeof (LOSObject) + LOS_CHUNK_SIZE - 1) >> LOS_CHUNK_BITS;
+               num_chunks = (obj_size + sizeof (LOSObject) + LOS_CHUNK_SIZE - 1) >> LOS_CHUNK_BITS;
                for (i = start_index; i < start_index + num_chunks; ++i)
                        g_assert (!section->free_chunk_map [i]);
        }
@@ -296,9 +303,9 @@ sgen_los_free_object (LOSObject *obj)
        SGEN_ASSERT (0, !obj->cardtable_mod_union, "We should never free a LOS object with a mod-union table.");
 
 #ifndef LOS_DUMMY
-       size_t size = obj->size;
-       SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)obj->size);
-       binary_protocol_empty (obj->data, obj->size);
+       mword size = sgen_los_object_size (obj);
+       SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)size);
+       binary_protocol_empty (obj->data, size);
 
        los_memory_usage -= size;
        los_num_objects--;
@@ -418,7 +425,7 @@ sgen_los_sweep (void)
                SGEN_ASSERT (0, !SGEN_OBJECT_IS_PINNED (bigobj->data), "Who pinned a LOS object?");
 
                if (bigobj->cardtable_mod_union) {
-                       sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, bigobj->size);
+                       sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, sgen_los_object_size (bigobj));
                        bigobj->cardtable_mod_union = NULL;
                }
 
@@ -502,7 +509,7 @@ sgen_ptr_is_in_los (char *ptr, char **start)
 
        *start = NULL;
        for (obj = los_object_list; obj; obj = obj->next) {
-               char *end = (char*)obj->data + obj->size;
+               char *end = (char*)obj->data + sgen_los_object_size (obj);
 
                if (ptr >= (char*)obj->data && ptr < end) {
                        *start = (char*)obj->data;
@@ -518,7 +525,7 @@ sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data)
        LOSObject *obj;
 
        for (obj = los_object_list; obj; obj = obj->next)
-               cb (obj->data, obj->size, user_data);
+               cb (obj->data, sgen_los_object_size (obj), user_data);
 }
 
 gboolean
@@ -543,7 +550,7 @@ mono_sgen_los_describe_pointer (char *ptr)
                mword size;
                gboolean pinned;
 
-               if ((char*)obj->data > ptr || (char*)obj->data + obj->size <= ptr)
+               if ((char*)obj->data > ptr || (char*)obj->data + sgen_los_object_size (obj) <= ptr)
                        continue;
 
                size = sgen_los_object_size (obj);
@@ -573,24 +580,25 @@ sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback)
        for (obj = los_object_list; obj; obj = obj->next) {
                GCVTable vt = SGEN_LOAD_VTABLE (obj->data);
                if (SGEN_VTABLE_HAS_REFERENCES (vt))
-                       callback ((mword)obj->data, (mword)obj->size);
+                       callback ((mword)obj->data, sgen_los_object_size (obj));
        }
 }
 
 static guint8*
 get_cardtable_mod_union_for_object (LOSObject *obj)
 {
+       mword size = sgen_los_object_size (obj);
        guint8 *mod_union = obj->cardtable_mod_union;
        guint8 *other;
        if (mod_union)
                return mod_union;
-       mod_union = sgen_card_table_alloc_mod_union ((char*)obj->data, obj->size);
+       mod_union = sgen_card_table_alloc_mod_union ((char*)obj->data, size);
        other = SGEN_CAS_PTR ((gpointer*)&obj->cardtable_mod_union, mod_union, NULL);
        if (!other) {
                SGEN_ASSERT (0, obj->cardtable_mod_union == mod_union, "Why did CAS not replace?");
                return mod_union;
        }
-       sgen_card_table_free_mod_union (mod_union, (char*)obj->data, obj->size);
+       sgen_card_table_free_mod_union (mod_union, (char*)obj->data, size);
        return other;
 }
 
@@ -615,7 +623,7 @@ sgen_los_scan_card_table (gboolean mod_union, ScanCopyContext ctx)
                        cards = NULL;
                }
 
-               sgen_cardtable_scan_object (obj->data, obj->size, cards, mod_union, ctx);
+               sgen_cardtable_scan_object (obj->data, sgen_los_object_size (obj), cards, mod_union, ctx);
        }
 }
 
@@ -629,7 +637,7 @@ sgen_los_count_cards (long long *num_total_cards, long long *num_marked_cards)
        for (obj = los_object_list; obj; obj = obj->next) {
                int i;
                guint8 *cards = sgen_card_table_get_card_scan_address ((mword) obj->data);
-               guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + obj->size - 1);
+               guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + sgen_los_object_size (obj) - 1);
                mword num_cards = (cards_end - cards) + 1;
 
                if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
@@ -655,16 +663,10 @@ sgen_los_update_cardtable_mod_union (void)
                if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
                        continue;
                sgen_card_table_update_mod_union (get_cardtable_mod_union_for_object (obj),
-                               (char*)obj->data, obj->size, NULL);
+                               (char*)obj->data, sgen_los_object_size (obj), NULL);
        }
 }
 
-mword
-sgen_los_object_size (LOSObject *obj)
-{
-       return obj->size & ~1L;
-}
-
 LOSObject*
 sgen_los_header_for_object (GCObject *data)
 {
index 7f629d6c356d07fb50b5aa15136d6f6669329cce..a2f9a63f103df7f67c0d70bb8596d5e306ca318e 100644 (file)
@@ -1,6 +1,6 @@
 SUBDIRS = assemblyresolve gc-descriptors
 
-check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform test-process-exit test-messages rm-empty-logs
+check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform test-process-exit test-messages test-unhandled-exception-2 rm-empty-logs
 check-full: test-sgen check-local
 check-parallel: compile-tests check-full
 
@@ -331,6 +331,7 @@ BASE_TEST_CS_SRC=           \
        bug-80392.2.cs          \
        dynamic-method-access.2.cs      \
        dynamic-method-finalize.2.cs    \
+       dynamic-method-stack-traces.cs  \
        bug-82194.2.cs  \
        anonarray.2.cs  \
        ienumerator-interfaces.2.cs     \
@@ -947,6 +948,7 @@ SGEN_TESTS =        \
        sgen-descriptors.exe    \
        sgen-gshared-vtype.exe  \
        sgen-domain-unload.exe  \
+       sgen-domain-unload-2.exe        \
        sgen-weakref-stress.exe \
        sgen-cementing-stress.exe       \
        sgen-case-23400.exe     \
@@ -1349,10 +1351,23 @@ test-oom: $(OOM_TESTS)
                MONO_GC_PARAMS=max-heap-size=16m                                                  $(RUNTIME) $$fn > $$fn.stdout || exit 1;      \
        done
 
+if HOST_WIN32
+test-unhandled-exception-2:
+else
+test-unhandled-exception-2: unhandled-exception.exe
+       @echo "Testing unhandled-exception_1 ..."; $(RUNTIME) $+ 1 1> unhandled-exception_1.exe.stdout 2> unhandled-exception_1.exe.stderr; if test "x$$?" != "x1";   then exit 1; fi;  \
+        echo "Testing unhandled-exception_2 ..."; $(RUNTIME) $+ 2 1> unhandled-exception_2.exe.stdout 2> unhandled-exception_2.exe.stderr; if test "x$$?" != "x0";   then exit 2; fi;  \
+        echo "Testing unhandled-exception_3 ..."; $(RUNTIME) $+ 3 1> unhandled-exception_3.exe.stdout 2> unhandled-exception_3.exe.stderr; if test "x$$?" != "x0";   then exit 3; fi;  \
+        echo "Testing unhandled-exception_4 ..."; $(RUNTIME) $+ 4 1> unhandled-exception_4.exe.stdout 2> unhandled-exception_4.exe.stderr; if test "x$$?" != "x0";   then exit 4; fi;  \
+        echo "Testing unhandled-exception_5 ..."; $(RUNTIME) $+ 5 1> unhandled-exception_5.exe.stdout 2> unhandled-exception_5.exe.stderr; if test "x$$?" != "x255"; then exit 5; fi;  \
+        echo "Testing unhandled-exception_6 ..."; $(RUNTIME) $+ 6 1> unhandled-exception_6.exe.stdout 2> unhandled-exception_6.exe.stderr; if test "x$$?" != "x0";   then exit 6; fi;  \
+        echo "Testing unhandled-exception_7 ..."; $(RUNTIME) $+ 7 1> unhandled-exception_7.exe.stdout 2> unhandled-exception_7.exe.stderr; if test "x$$?" != "x0";   then exit 7; fi;  \
+        echo "Testing unhandled-exception_8 ..."; $(RUNTIME) $+ 8 1> unhandled-exception_8.exe.stdout 2> unhandled-exception_8.exe.stderr; if test "x$$?" != "x3";   then exit 8; fi
+endif
 
 noinst_LTLIBRARIES = libtest.la
 
-AM_CPPFLAGS = $(GLIB_CFLAGS) $(GMODULE_CFLAGS)
+AM_CPPFLAGS = $(GLIB_CFLAGS)
 
 if HOST_WIN32
 # gcc-3.4.4 emits incorrect code when making indirect calls to stdcall functions using a tail call
diff --git a/mono/tests/dynamic-method-stack-traces.cs b/mono/tests/dynamic-method-stack-traces.cs
new file mode 100644 (file)
index 0000000..965c525
--- /dev/null
@@ -0,0 +1,86 @@
+using System;
+using System.Threading;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.ExceptionServices;
+using System.Diagnostics;
+
+public class A
+{
+       public static Exception Caught;
+
+       public static void ThrowMe()
+       {
+               Exception e;
+               try
+               {
+                       throw new Exception("test");
+               }
+               catch (Exception e2)
+               {
+                       e = e2;
+               }
+
+               var edi = ExceptionDispatchInfo.Capture(e);
+
+               edi.Throw();
+       }
+
+       public static void Handler(Exception e)
+       {
+               Caught = e;
+       }
+}
+
+public class Example
+{
+       public static int Main()
+       {
+               TT();
+               string expected = A.Caught.StackTrace.ToString ();
+
+               for (int i = 0; i < 1000; ++i) {
+                       Thread t = new Thread (delegate () {
+                                       TT ();
+                               });
+                       t.Start ();
+                       t.Join ();
+                       GC.Collect ();
+                       GC.WaitForPendingFinalizers ();
+                       if (A.Caught.StackTrace != expected) {
+                               Console.WriteLine ("FAILED");
+                               return 1;
+                       }
+               }
+               return 0;
+       }
+
+       static void TT()
+       {
+               DynamicMethod multiplyHidden = new DynamicMethod(
+                       "",
+                       typeof(void), new[] { typeof(int) }, typeof(Example));
+
+               ILGenerator ig = multiplyHidden.GetILGenerator();
+
+               ig.BeginExceptionBlock();
+
+               ig.Emit(OpCodes.Call, typeof(A).GetMethod("ThrowMe"));
+
+               ig.BeginCatchBlock(typeof(Exception));
+
+               ig.Emit(OpCodes.Call, typeof(A).GetMethod("Handler"));
+
+               ig.EndExceptionBlock();
+
+               ig.Emit(OpCodes.Ret);
+
+               var invoke = (Action<int>)
+                       multiplyHidden.CreateDelegate(
+                               typeof(Action<int>)
+
+                       );
+
+               invoke(1);
+       }
+}
index 924a643418f60d4ea9ebb708ae66474555a54e71..85b35589de88301b046abab0954aa49ad6ee0f52 100644 (file)
@@ -3825,7 +3825,7 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                if (a1->A != 42)
                        return 8;
 
-               if (!fabs (a1->B - 3.1415) < 0.001)
+               if (!(fabs (a1->B - 3.1415) < 0.001))
                        return 9;
 
                break;
@@ -3852,7 +3852,7 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                if (a1->A != 42)
                        return 5;
 
-               if (!fabs (a1->B - 3.1415) < 0.001)
+               if (!(fabs (a1->B - 3.1415) < 0.001))
                        return 6;
 
                break;
index 2ce4a3c4d78f7e9e00f22a0d81ab57292d22cc48..205d10ca16e98838c73ff9da01053e166f4ce530 100644 (file)
@@ -12,14 +12,26 @@ public class Foo  {
                resurrect = this;
        }
 
+       public static void EnterMonitor (object obj)
+       {
+               for (int i = 0; i < 257; i++)
+                       Monitor.Enter (obj);
+       }
+
+       public static void ExitMonitor (object obj)
+       {
+               for (int i = 0; i < 257; i++)
+                       Monitor.Exit (obj);
+       }
+
        public static void CreateFoo (int level)
        {
                if (level == 0) {
                        reference = new Foo ();
 
                        /* Allocate a MonoThreadsSync for the object */
-                       Monitor.Enter (reference);
-                       Monitor.Exit (reference);
+                       EnterMonitor (reference);
+                       ExitMonitor (reference);
                        reference = null;
                } else {
                        CreateFoo (level - 1);
@@ -52,7 +64,7 @@ public class Foo  {
                        /* Make sure these are not collected */
                        list.Add (foo);
 
-                       Monitor.Enter (foo);
+                       EnterMonitor (foo);
                }
        }
 } 
index b7ff6475d23cdb14ba9877754c6a53446d341625..2145f0561c00cfea150b74a07b4b78c70a1ce635 100644 (file)
@@ -54,10 +54,11 @@ class main {
                        b.test_exception ();
                }
                catch (SynchronizationLockException ex) {
-                       return 1;
+                       // OK
                }
                catch (Exception ex) {
-                       // OK
+                       // The other exception should be overwritten by the lock one
+                       return 1;
                }
 
                Console.WriteLine ("Test4...");
@@ -81,10 +82,10 @@ class main {
                        d ();
                }
                catch (SynchronizationLockException ex) {
-                       return 2;
+                       // OK
                }
                catch (Exception ex) {
-                       // OK
+                       return 2;
                }
 
                return 0;
diff --git a/mono/tests/suspend-stress-test.cs b/mono/tests/suspend-stress-test.cs
new file mode 100644 (file)
index 0000000..3289a3e
--- /dev/null
@@ -0,0 +1,223 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Diagnostics;
+using System.IO;
+
+/*
+TODO
+       Some tests are much more expensive than others (on cycles and synchronization), add a calibration step to figure out duration.
+       Some tests are more disrruptive than others, add weights to tests so some are picked more frequently.
+       The workload is too static, add some background generation noise tests.
+       The workload is too stable, add perturbance on the number of available tasks.
+       Fuse threadpool with non threadpool workloads by firing some tasks as separate threads.
+       Add an external watchdog so we can run the stress test in a loop for very long times and get results out of it.
+       We don't have enough tests, add one per locking operation we got in the runtime.
+
+Missing tests:
+       Ephemerons
+       Dynamic methods
+       Regular SRE
+       Remoting / Transparent Proxies
+       Context locals
+       Thread locals
+       Finalizers
+       Async socket IO
+*/
+
+class Driver {
+       static bool stop_please;
+       const int TEST_DURATION = 1000;
+
+       static object very_contended_object = new object ();
+
+       static bool Ok (ref int loops) {
+               if (loops == -1)
+                       return !stop_please;
+               if (loops == 0)
+                       return false;
+               loops--;
+               return true;
+
+       }
+       static void MonitorEnterInALoop (int loops)
+       {
+               while (Ok (ref loops)) {
+                       if (Monitor.TryEnter (very_contended_object, 100)) {
+                               Thread.Sleep (30);
+                               Monitor.Exit (very_contended_object);
+                       }
+               }
+       }
+
+       static void AllocObjectInALoop (int loops) {
+               while (Ok (ref loops)) {
+                       var a = new object ();
+                       var b = new byte [100];
+               }
+       }
+
+       static void AllocDomainInALoop (int loops) {
+               int count = 0;
+               while (Ok (ref loops)) {
+                       var a = AppDomain.CreateDomain ("test_domain_" + ++count);
+                       AppDomain.Unload (a);
+               }
+       }
+
+       static void FileIO (int loops) {
+               while (Ok (ref loops)) {
+                       var dir = Path.GetTempFileName () + "_" + Thread.CurrentThread.ManagedThreadId;
+                       Directory.CreateDirectory (dir);
+                       Directory.Delete (dir);
+                       
+               }
+       }
+
+    static void Timer_Elapsed(object sender, EventArgs e)
+    {
+        HashSet<string> h = new HashSet<string>();
+        for (int j = 0; j < 500; j++)
+        {
+            h.Add(""+j+""+j);
+        }
+    }
+
+       //From sgen-new-threads-dont-join-stw
+       static void TimerStress (int loops) {
+               while (Ok (ref loops)) {
+                       System.Timers.Timer timer = new System.Timers.Timer();
+            timer.Elapsed += Timer_Elapsed;
+            timer.AutoReset = false;
+            timer.Interval = 500;
+            timer.Start ();
+               }
+       }
+
+       //from sgen-weakref-stress
+       static void WeakRefStress (int loops) {
+               while (Ok (ref loops)) {
+                  for (int j = 0; j < 500; ++j) {
+                      new WeakReference (new object ());
+                  }
+               }
+       }
+       static Tuple<Action<int>,string>[] available_tests = new [] {
+               Tuple.Create (new Action<int> (MonitorEnterInALoop), "monitor"),
+               Tuple.Create (new Action<int> (AllocObjectInALoop), "alloc"),
+               Tuple.Create (new Action<int> (AllocDomainInALoop), "appdomain"),
+               Tuple.Create (new Action<int> (FileIO), "file-io"),
+               Tuple.Create (new Action<int> (TimerStress), "timers"),
+               Tuple.Create (new Action<int> (WeakRefStress), "weakref"),
+       };
+
+       static void GcPump (int timeInMillis)
+       {
+               var sw = Stopwatch.StartNew ();
+               do {
+                       GC.Collect ();
+                       Thread.Sleep (1);
+               } while (sw.ElapsedMilliseconds < timeInMillis);
+               stop_please = true;
+       }
+
+       const int minTpSteps = 1;
+       const int maxTpSteps = 30;
+
+       static void QueueStuffUsingTpl (int threadCount) {
+               int pendingJobs = 0;
+               int maxPending = threadCount * 2;
+               int generatorIdx = 0;
+               Random rand = new Random (0);
+
+               while (!stop_please) {
+                       while (pendingJobs < maxPending) {
+                               var task = available_tests [generatorIdx++ % available_tests.Length].Item1;
+                               int steps = rand.Next(minTpSteps, maxTpSteps);
+                               ThreadPool.QueueUserWorkItem (_ => {
+                                       task (steps);
+                                       Interlocked.Decrement (ref pendingJobs);
+                               });
+                               Interlocked.Increment (ref pendingJobs);
+                       }
+                       Thread.Sleep (1);
+               }
+               while (pendingJobs > 0)
+                       Thread.Sleep (1);
+       }
+
+       static void DynamicLoadGenerator (int threadCount, int timeInMillis) {
+               var t = new Thread (() => QueueStuffUsingTpl (threadCount));
+               t.Start ();
+
+               GcPump (timeInMillis);
+
+               t.Join ();
+       }
+
+       static void StaticLoadGenerator (int threadCount, int testIndex, int timeInMillis) {
+               List<Thread> threads = new List<Thread> ();
+
+               for (int i = 0; i < threadCount; ++i) {
+                       var dele = (testIndex >= 0 ? available_tests [testIndex] : available_tests [i % available_tests.Length]).Item1;
+                       var t = new Thread (() => dele (-1));
+                       t.Start ();
+                       threads.Add (t);
+               }
+
+               GcPump (timeInMillis);
+
+               foreach (var t in threads)
+                       t.Join ();
+       }
+       
+       static int ParseTestName (string name) {
+               for (int i = 0; i < available_tests.Length; ++i) {
+                       if (available_tests[i].Item2 == name)
+                               return i;
+               }
+               Console.WriteLine ("Invalid test name {0}", name);
+               Environment.Exit (2);
+               return -1;
+       }
+
+       static int Main (string[] args) {
+               int threadCount = Environment.ProcessorCount - 1;
+               int timeInMillis = TEST_DURATION;
+               int testIndex = -1;
+               bool tpLoadGenerator = false;
+               string testName = "static";
+               
+
+               for (int j = 0; j < args.Length;) {
+                       if ((args [j] == "--duration") || (args [j] == "-d")) {
+                               timeInMillis = Int32.Parse (args [j + 1]);
+                               j += 2;
+                       } else if ((args [j] == "--test") || (args [j] == "-t")) {
+                               if (args [j + 1] == "static")
+                                       testIndex = -1;
+                               else if (args [j + 1] == "tp")
+                                       tpLoadGenerator = true;
+                               else
+                                       testIndex = ParseTestName (testName = args [j + 1]);
+                               j += 2;
+                       } else  if ((args [j] == "--thread-count") || (args [j] == "-tc")) {
+                               threadCount = Int32.Parse (args [j + 1]);
+                               j += 2;
+                       }else {
+                               Console.WriteLine ("Unknown argument: " + args [j]);
+                               return 1;
+                       }
+        }
+
+               if (tpLoadGenerator) {
+                       Console.WriteLine ("tp window {0} duration {1}", threadCount, timeInMillis);
+                       DynamicLoadGenerator (threadCount, timeInMillis);
+               } else {
+                       Console.WriteLine ("thread count {0} duration {1} test {2}", threadCount, timeInMillis, testName);
+                       StaticLoadGenerator (threadCount, testIndex, timeInMillis);
+               }
+
+               return 0;
+       }
+}
\ No newline at end of file
index a63b63fa5c6d4c66262f59a661bbcc8710ac771e..9d56cd8c365a121503d886399b40ec3d2a5c5081 100644 (file)
@@ -76,10 +76,11 @@ class Tests {
                        b.test_exception ();
                }
                catch (SynchronizationLockException ex) {
-                       return 1;
+                       // OK
                }
                catch (Exception ex) {
-                       // OK
+                       // The other exception should be overwritten by the lock one
+                       return 1;
                }
                if (is_synchronized (b))
                        return 1;
@@ -113,10 +114,10 @@ class Tests {
                        d ();
                }
                catch (SynchronizationLockException ex) {
-                       return 2;
+                       // OK
                }
                catch (Exception ex) {
-                       // OK
+                       return 2;
                }
                if (is_synchronized (b))
                        return 1;
diff --git a/mono/tests/unhandled-exception.cs b/mono/tests/unhandled-exception.cs
new file mode 100644 (file)
index 0000000..7658e07
--- /dev/null
@@ -0,0 +1,193 @@
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+class CustomException : Exception
+{
+}
+
+class CustomException2 : Exception
+{
+}
+
+
+class CrossDomain : MarshalByRefObject
+{
+       public Action NewDelegateWithTarget ()
+       {
+               return new Action (Bar);
+       }
+
+       public Action NewDelegateWithoutTarget ()
+       {
+               return () => { throw new CustomException (); };
+       }
+
+       public void Bar ()
+       {
+               throw new CustomException ();
+       }
+}
+
+class Driver {
+       static ManualResetEvent mre = new ManualResetEvent (false);
+
+       static void DoTest1 ()
+       {
+               mre.Reset ();
+
+               var t = new Thread (new ThreadStart (() => { try { throw new CustomException (); } finally { mre.Set (); } }));
+               t.Start ();
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+
+               t.Join ();
+       }
+
+       static void DoTest2 ()
+       {
+               mre.Reset ();
+
+               var a = new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } });
+               var ares = a.BeginInvoke (null, null);
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {                     
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void DoTest3 ()
+       {
+               mre.Reset ();
+
+               ThreadPool.QueueUserWorkItem (_ => { try { throw new CustomException (); } finally { mre.Set (); } });
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+       }
+
+       static void DoTest4 ()
+       {
+               mre.Reset ();
+
+               var t = Task.Factory.StartNew (new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } }));
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+
+               try {
+                       t.Wait ();
+                       throw new Exception ();
+               } catch (AggregateException ae) {
+                       if (!(ae.InnerExceptions [0] is CustomException))
+                               Environment.Exit (4);
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+       
+       class FinalizedClass
+       {
+               ~FinalizedClass ()
+               {
+                       try {
+                               throw new CustomException ();
+                       } finally {
+                               mre.Set ();
+                       }
+               }
+       }
+
+       static void DoTest5 ()
+       {
+               mre.Reset ();
+
+               new FinalizedClass();
+
+               GC.Collect ();
+               GC.WaitForPendingFinalizers ();
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+       }
+
+       static void DoTest6 ()
+       {
+               ManualResetEvent mre2 = new ManualResetEvent (false);
+
+               mre.Reset ();
+
+               var a = new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } });
+               var ares = a.BeginInvoke (_ => { mre2.Set (); throw new CustomException2 (); }, null);
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+               if (!mre2.WaitOne (5000))
+                       Environment.Exit (22);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void DoTest7 ()
+       {
+               var cd = (CrossDomain) AppDomain.CreateDomain ("ad").CreateInstanceAndUnwrap (typeof(CrossDomain).Assembly.FullName, "CrossDomain");
+
+               var a = cd.NewDelegateWithoutTarget ();
+               var ares = a.BeginInvoke (delegate { throw new CustomException2 (); }, null);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void DoTest8 ()
+       {
+               var cd = (CrossDomain) AppDomain.CreateDomain ("ad").CreateInstanceAndUnwrap (typeof(CrossDomain).Assembly.FullName, "CrossDomain");
+
+               var a = cd.NewDelegateWithTarget ();
+               var ares = a.BeginInvoke (delegate { throw new CustomException2 (); }, null);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void Main (string[] args)
+       {
+               switch (int.Parse (args [0])) {
+               case 1: DoTest1 (); break;
+               case 2: DoTest2 (); break;
+               case 3: DoTest3 (); break;
+               case 4: DoTest4 (); break;
+               case 5: DoTest5 (); break;
+               case 6: DoTest6 (); break;
+               case 7: DoTest7 (); break;
+               case 8: DoTest8 (); break;
+               default: throw new ArgumentOutOfRangeException ();
+               }
+               Environment.Exit (0);
+       }
+}
index bdafa56291eb3a9bab4d764c83e0c29066ee1e52..fec63391ed85d337ac078ed81ebcc71014c73bb0 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "utils/mono-threads.h"
 #include "utils/mono-conc-hashtable.h"
+#include "utils/checked-build.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -37,11 +38,23 @@ single_writer_single_reader (void)
        int res = 0;
 
        mono_mutex_init (&mutex);
-       h = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       h = mono_conc_hashtable_new (NULL, NULL);
+
+       mono_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (10), GUINT_TO_POINTER (20));
+       mono_mutex_unlock (&mutex);
+
+       mono_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (30), GUINT_TO_POINTER (40));
+       mono_mutex_unlock (&mutex);
+
+       mono_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (50), GUINT_TO_POINTER (60));
+       mono_mutex_unlock (&mutex);
+
+       mono_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (2), GUINT_TO_POINTER (3));
+       mono_mutex_unlock (&mutex);
 
        if (mono_conc_hashtable_lookup (h, GUINT_TO_POINTER (30)) != GUINT_TO_POINTER (40))
                res = 1;
@@ -60,6 +73,7 @@ single_writer_single_reader (void)
 }
 
 static MonoConcurrentHashTable *hash;
+static mono_mutex_t global_mutex;
 
 static void*
 pw_sr_thread (void *arg)
@@ -67,8 +81,11 @@ pw_sr_thread (void *arg)
        int i, idx = 1000 * GPOINTER_TO_INT (arg);
        mono_thread_info_attach ((gpointer)&arg);
 
-       for (i = 0; i < 1000; ++i)
+       for (i = 0; i < 1000; ++i) {
+               mono_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + idx), GINT_TO_POINTER (i + 1));
+               mono_mutex_unlock (&global_mutex);
+       }
        return NULL;
 }
 
@@ -76,11 +93,10 @@ static int
 parallel_writer_single_reader (void)
 {
        pthread_t a,b,c;
-       mono_mutex_t mutex;
        int i, j, res = 0;
 
-       mono_mutex_init (&mutex);
-       hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_mutex_init (&global_mutex);
+       hash = mono_conc_hashtable_new (NULL, NULL);
 
        pthread_create (&a, NULL, pw_sr_thread, GINT_TO_POINTER (1));
        pthread_create (&b, NULL, pw_sr_thread, GINT_TO_POINTER (2));
@@ -101,7 +117,7 @@ parallel_writer_single_reader (void)
 
 done:
        mono_conc_hashtable_destroy (hash);
-       mono_mutex_destroy (&mutex);
+       mono_mutex_destroy (&global_mutex);
        if (res)
                printf ("PAR_WRITER_SINGLE_READER TEST FAILED %d\n", res);
        return res;
@@ -129,22 +145,29 @@ static int
 single_writer_parallel_reader (void)
 {
        pthread_t a,b,c;
-       mono_mutex_t mutex;
        gpointer ra, rb, rc;
        int i, res = 0;
        ra = rb = rc = GINT_TO_POINTER (1);
 
-       mono_mutex_init (&mutex);
-       hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_mutex_init (&global_mutex);
+       hash = mono_conc_hashtable_new (NULL, NULL);
 
        pthread_create (&a, NULL, pr_sw_thread, GINT_TO_POINTER (0));
        pthread_create (&b, NULL, pr_sw_thread, GINT_TO_POINTER (1));
        pthread_create (&c, NULL, pr_sw_thread, GINT_TO_POINTER (2));
 
        for (i = 0; i < 100; ++i) {
+               mono_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i +   0 + 1), GINT_TO_POINTER ((i +   0) * 2 + 1));
+               mono_mutex_unlock (&global_mutex);
+
+               mono_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 100 + 1), GINT_TO_POINTER ((i + 100) * 2 + 1));
+               mono_mutex_unlock (&global_mutex);
+
+               mono_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 200 + 1), GINT_TO_POINTER ((i + 200) * 2 + 1));
+               mono_mutex_unlock (&global_mutex);
        }
 
        pthread_join (a, &ra);
@@ -153,7 +176,7 @@ single_writer_parallel_reader (void)
        res = GPOINTER_TO_INT (ra) + GPOINTER_TO_INT (rb) + GPOINTER_TO_INT (rc);
 
        mono_conc_hashtable_destroy (hash);
-       mono_mutex_destroy (&mutex);
+       mono_mutex_destroy (&global_mutex);
        if (res)
                printf ("SINGLE_WRITER_PAR_READER TEST FAILED %d\n", res);
        return res;
@@ -189,8 +212,11 @@ pw_pr_w_add_thread (void *arg)
 
        mono_thread_info_attach ((gpointer)&arg);
 
-       for (i = idx; i < idx + 1000; i++)
+       for (i = idx; i < idx + 1000; i++) {
+               mono_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 1), GINT_TO_POINTER (i + 1));
+               mono_mutex_unlock (&global_mutex);
+       }
        return NULL;
 }
 
@@ -201,8 +227,11 @@ pw_pr_w_del_thread (void *arg)
 
        mono_thread_info_attach ((gpointer)&arg);
 
-       for (i = idx; i < idx + 1000; i++)
+       for (i = idx; i < idx + 1000; i++) {
+               mono_mutex_lock (&global_mutex);
                mono_conc_hashtable_remove (hash, GINT_TO_POINTER (i + 1));
+               mono_mutex_unlock (&global_mutex);
+       }
        return NULL;
 }
 
@@ -210,14 +239,13 @@ static int
 parallel_writer_parallel_reader (void)
 {
        pthread_t wa, wb, wc, ra, rb, rc;
-       mono_mutex_t mutex;
        gpointer a, b, c;
        int res = 0, i;
 
        srand(time(NULL));
 
-       mono_mutex_init (&mutex);
-       hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_mutex_init (&global_mutex);
+       hash = mono_conc_hashtable_new (NULL, NULL);
 
        for (i = 0; i < 2; i++) {
                running = 1;
@@ -256,7 +284,7 @@ parallel_writer_parallel_reader (void)
                printf ("PAR_WRITER_PAR_READER TEST FAILED %d %d %d\n", GPOINTER_TO_INT (a), GPOINTER_TO_INT (b), GPOINTER_TO_INT (c));
 
        mono_conc_hashtable_destroy (hash);
-       mono_mutex_destroy (&mutex);
+       mono_mutex_destroy (&global_mutex);
 
        return res;
 }
@@ -264,15 +292,14 @@ parallel_writer_parallel_reader (void)
 static void G_GNUC_UNUSED
 benchmark_conc (void)
 {
-       mono_mutex_t mutex;
        MonoConcurrentHashTable *h;
        int i, j;
 
-       mono_mutex_init (&mutex);
-       h = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       h = mono_conc_hashtable_new (NULL, NULL);
 
-       for (i = 1; i < 10 * 1000; ++i)
+       for (i = 1; i < 10 * 1000; ++i) {
                mono_conc_hashtable_insert (h, GUINT_TO_POINTER (i), GUINT_TO_POINTER (i));
+       }
 
 
        for (j = 0; j < 100000; ++j)
@@ -280,8 +307,6 @@ benchmark_conc (void)
                        mono_conc_hashtable_lookup (h, GUINT_TO_POINTER (i));
 
        mono_conc_hashtable_destroy (h);
-       mono_mutex_destroy (&mutex);
-
 }
 
 static void G_GNUC_UNUSED
@@ -309,6 +334,7 @@ main (void)
        MonoThreadInfoCallbacks cb = { NULL };
        int res = 0;
 
+       CHECKED_MONO_INIT ();
        mono_threads_init (&cb, sizeof (MonoThreadInfo));
        mono_thread_info_attach ((gpointer)&cb);
 
index 4e804ebe468742cbe86f0b629a4550a3db87c183..e1b1034327e1db36902cac3fce48c32a566a99b7 100644 (file)
@@ -109,6 +109,7 @@ monoutils_sources = \
        mono-threads-openbsd.c  \
        mono-threads-android.c  \
        mono-threads.h  \
+       mono-threads-api.h      \
        mono-threads-coop.c     \
        mono-threads-coop.h     \
        mono-tls.h      \
@@ -139,7 +140,9 @@ monoutils_sources = \
        memfuncs.c \
        memfuncs.h \
        parse.c \
-       parse.h
+       parse.h \
+       checked-build.c \
+       checked-build.h
 
 arch_sources = 
 
diff --git a/mono/utils/checked-build.c b/mono/utils/checked-build.c
new file mode 100644 (file)
index 0000000..7dd6599
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * checked-build.c: Expensive asserts used when mono is built with --with-checked-build=yes
+ *
+ * Author:
+ *     Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2015 Xamarin
+ */
+#include <config.h>
+#ifdef CHECKED_BUILD
+
+#include <mono/utils/checked-build.h>
+#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-tls.h>
+#include <glib.h>
+
+#define MAX_NATIVE_BT 6
+#define MAX_NATIVE_BT_PROBE (MAX_NATIVE_BT + 5)
+#define MAX_TRANSITIONS 3
+
+
+#ifdef HAVE_BACKTRACE_SYMBOLS
+#include <execinfo.h>
+
+//XXX We should collect just the IPs and lazily symbolificate them.
+static int
+collect_backtrace (gpointer out_data[])
+{
+       return backtrace (out_data, MAX_NATIVE_BT_PROBE);
+}
+
+static char*
+translate_backtrace (gpointer native_trace[], int size)
+{
+       char **names = backtrace_symbols (native_trace, size);
+       GString* bt = g_string_sized_new (100);
+
+       int i, j = -1;
+
+       //Figure out the cut point of useless backtraces
+       //We'll skip up to the caller of checked_build_thread_transition
+       for (i = 0; i < size; ++i) {
+               if (strstr (names [i], "checked_build_thread_transition")) {
+                       j = i + 1;
+                       break;
+               }
+       }
+
+       if (j == -1)
+               j = 0;
+       for (i = j; i < size; ++i) {
+               if (i - j <= MAX_NATIVE_BT)
+                       g_string_append_printf (bt, "\tat %s\n", names [i]);
+       }
+
+       free (names);
+       return g_string_free (bt, FALSE);
+}
+
+#else
+
+static int
+collect_backtrace (gpointer out_data[])
+{
+       return 0;
+}
+
+static char*
+translate_backtrace (gpointer native_trace[], int size)
+{
+       return g_strdup ("\tno backtrace available\n");
+}
+
+#endif
+
+
+typedef struct {
+       GPtrArray *transitions;
+} CheckState;
+
+typedef struct {
+       const char *name;
+       int from_state, next_state, suspend_count, suspend_count_delta, size;
+       gpointer backtrace [MAX_NATIVE_BT_PROBE];
+} ThreadTransition;
+
+static MonoNativeTlsKey thread_status;
+
+void
+checked_build_init (void)
+{
+       mono_native_tls_alloc (&thread_status, NULL);
+}
+
+static CheckState*
+get_state (void)
+{
+       CheckState *state = mono_native_tls_get_value (thread_status);
+       if (!state) {
+               state = g_new0 (CheckState, 1);
+               state->transitions = g_ptr_array_new ();
+               mono_native_tls_set_value (thread_status, state);
+       }
+
+       return state;
+}
+
+static void
+free_transition (ThreadTransition *t)
+{
+       g_free (t);
+}
+
+void
+checked_build_thread_transition (const char *transition, void *info, int from_state, int suspend_count, int next_state, int suspend_count_delta)
+{
+       MonoThreadInfo *cur = mono_thread_info_current_unchecked ();
+       CheckState *state = get_state ();
+       /* We currently don't record external changes as those are hard to reason about. */
+       if (cur != info)
+               return;
+
+       if (state->transitions->len >= MAX_TRANSITIONS)
+               free_transition (g_ptr_array_remove_index (state->transitions, 0));
+
+       ThreadTransition *t = g_new0 (ThreadTransition, 1);
+       t->name = transition;
+       t->from_state = from_state;
+       t->next_state = next_state;
+       t->suspend_count = suspend_count;
+       t->suspend_count_delta = suspend_count_delta;
+       t->size = collect_backtrace (t->backtrace);
+       g_ptr_array_add (state->transitions, t);
+}
+
+static void
+assertion_fail (const char *msg, ...)
+{
+       int i;
+       GString* err = g_string_sized_new (100);
+       CheckState *state = get_state ();
+
+       g_string_append_printf (err, "Assertion failure in thread %p due to: ", mono_native_thread_id_get ());
+
+       va_list args;
+       va_start (args, msg);
+       g_string_append_vprintf (err, msg, args);
+       va_end (args);
+
+       g_string_append_printf (err, "\nLast %d state transitions: (most recent first)\n", state->transitions->len);
+
+       for (i = state->transitions->len - 1; i >= 0; --i) {
+               ThreadTransition *t = state->transitions->pdata [i];
+               char *bt = translate_backtrace (t->backtrace, t->size);
+               g_string_append_printf (err, "[%s] %s -> %s (%d) %s%d at:\n%s",
+                       t->name,
+                       mono_thread_state_name (t->from_state),
+                       mono_thread_state_name (t->next_state),
+                       t->suspend_count,
+                       t->suspend_count_delta > 0 ? "+" : "", //I'd like to see this sort of values: -1, 0, +1
+                       t->suspend_count_delta,
+                       bt);
+               g_free (bt);
+       }
+
+       g_error (err->str);
+       g_string_free (err, TRUE);
+}
+
+void
+assert_gc_safe_mode (void)
+{
+       MonoThreadInfo *cur = mono_thread_info_current ();
+       int state;
+
+       if (!cur)
+               assertion_fail ("Expected GC Safe mode but thread is not attached");
+
+       switch (state = mono_thread_info_current_state (cur)) {
+       case STATE_BLOCKING:
+       case STATE_BLOCKING_AND_SUSPENDED:
+               break;
+       default:
+               assertion_fail ("Expected GC Safe mode but was in %s state", mono_thread_state_name (state));
+       }
+}
+
+void
+assert_gc_unsafe_mode (void)
+{
+       MonoThreadInfo *cur = mono_thread_info_current ();
+       int state;
+
+       if (!cur)
+               assertion_fail ("Expected GC Unsafe mode but thread is not attached");
+
+       switch (state = mono_thread_info_current_state (cur)) {
+       case STATE_RUNNING:
+       case STATE_ASYNC_SUSPEND_REQUESTED:
+       case STATE_SELF_SUSPEND_REQUESTED:
+               break;
+       default:
+               assertion_fail ("Expected GC Unsafe mode but was in %s state", mono_thread_state_name (state));
+       }
+}
+
+void
+assert_gc_neutral_mode (void)
+{
+       MonoThreadInfo *cur = mono_thread_info_current ();
+       int state;
+
+       if (!cur)
+               assertion_fail ("Expected GC Neutral mode but thread is not attached");
+
+       switch (state = mono_thread_info_current_state (cur)) {
+       case STATE_RUNNING:
+       case STATE_ASYNC_SUSPEND_REQUESTED:
+       case STATE_SELF_SUSPEND_REQUESTED:
+       case STATE_BLOCKING:
+       case STATE_BLOCKING_AND_SUSPENDED:
+               break;
+       default:
+               assertion_fail ("Expected GC Neutral mode but was in %s state", mono_thread_state_name (state));
+       }
+}
+
+#endif /* CHECKED_BUILD */
diff --git a/mono/utils/checked-build.h b/mono/utils/checked-build.h
new file mode 100644 (file)
index 0000000..d2ba9ec
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * checked-build.h: Expensive asserts used when mono is built with --with-checked-build=yes
+ *
+ * Author:
+ *     Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2015 Xamarin
+ */
+
+#ifndef __CHECKED_BUILD_H__
+#define __CHECKED_BUILD_H__
+
+#include <config.h>
+
+#ifdef CHECKED_BUILD
+
+/*
+GC runtime modes rules:
+
+- GC Safe
+Can:
+Call into foreigh functions.
+Call GC Safe or Neutral modes functions.
+Read from pinned managed memory.
+
+Cannot:
+Touch managed memory (read/write).
+Be dettached.
+
+What's good for?
+Doing blocking calls.
+
+- GC Unsafe
+Can:
+Touch managed memory (read/write).
+Call GC Unsafe or Neutral modes functions.
+
+Cannot:
+Call foreign native code (embedder callbacks, pinvokes, etc)
+Call into any Blocking functions/syscalls (mutexes, IO, etc)
+Be dettached.
+
+What's good for?
+Poking into managed memory.
+
+-- GC Neutral
+Can:
+Call other GC Neutral mode functions.
+
+Cannot:
+Touch managed memory.
+Call foreign native code (embedder callbacks, pinvokes, etc)
+Call into any Blocking functions/syscalls (mutexes, IO, etc)
+Be dettached.
+
+What's good for?
+Functions that can be called from both coop or preept modes.
+
+*/
+
+#define MONO_REQ_GC_SAFE_MODE do {     \
+       assert_gc_safe_mode (); \
+} while (0);
+
+#define MONO_REQ_GC_UNSAFE_MODE do {   \
+       assert_gc_unsafe_mode ();       \
+} while (0);
+
+#define MONO_REQ_GC_NEUTRAL_MODE do {  \
+       assert_gc_neutral_mode ();      \
+} while (0);
+
+/*
+This can be called by embedders
+*/
+#define MONO_REQ_API_ENTRYPOINT
+
+/*
+The JIT will generate code that will land on this function
+*/
+#define MONO_REQ_RUNTIME_ENTRYPOINT
+
+#define CHECKED_MONO_INIT() do { checked_build_init (); } while (0)
+
+#define CHECKED_BUILD_THREAD_TRANSITION(transition, info, from_state, suspend_count, next_state, suspend_count_delta) do {     \
+       checked_build_thread_transition (transition, info, from_state, suspend_count, next_state, suspend_count_delta); \
+} while (0)
+
+void assert_gc_safe_mode (void);
+void assert_gc_unsafe_mode (void);
+void assert_gc_neutral_mode (void);
+
+void checked_build_init (void);
+void checked_build_thread_transition(const char *transition, void *info, int from_state, int suspend_count, int next_state, int suspend_count_delta);
+
+#else
+
+#define MONO_REQ_GC_SAFE_MODE
+#define MONO_REQ_GC_UNSAFE_MODE
+#define MONO_REQ_GC_NEUTRAL_MODE
+#define MONO_REQ_API_ENTRYPOINT
+#define MONO_REQ_RUNTIME_ENTRYPOINT
+
+#define CHECKED_MONO_INIT()
+#define CHECKED_BUILD_THREAD_TRANSITION(transition, info, from_state, suspend_count, next_state, suspend_count_delta)
+
+#endif /* CHECKED_BUILD */
+
+#endif
index 1f77f5463650053a83b8a4e0d467b0e83fd11bc8..a13c0b7798420c2ef1a533540960230c2ce96201 100644 (file)
 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
 #endif
 
-#elif defined(TARGET_MACH) && 0
+#elif defined(TARGET_MACH) && (defined(__i386__) || defined(__x86_64__))
 
-#define MONO_HAVE_FAST_TLS
+#define MONO_HAVE_FAST_TLS 1
 #define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
 #define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
 #define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
index 6aaa04f07dd585fb9fd58637c350d09fcbca87da..30521b2af9ef81e221add9051db5cbf3f46a299f 100644 (file)
@@ -30,7 +30,6 @@ struct _MonoConcurrentHashTable {
        volatile conc_table *table; /* goes to HP0 */
        GHashFunc hash_func;
        GEqualFunc equal_func;
-       mono_mutex_t *mutex;
        int element_count;
        int overflow_count;
        GDestroyNotify key_destroy_func;
@@ -111,10 +110,9 @@ expand_table (MonoConcurrentHashTable *hash_table)
 
 
 MonoConcurrentHashTable*
-mono_conc_hashtable_new (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func)
+mono_conc_hashtable_new (GHashFunc hash_func, GEqualFunc key_equal_func)
 {
        MonoConcurrentHashTable *res = g_new0 (MonoConcurrentHashTable, 1);
-       res->mutex = mutex;
        res->hash_func = hash_func ? hash_func : g_direct_hash;
        res->equal_func = key_equal_func ? key_equal_func : g_direct_equal;
        // res->equal_func = g_direct_equal;
@@ -125,9 +123,9 @@ mono_conc_hashtable_new (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc ke
 }
 
 MonoConcurrentHashTable*
-mono_conc_hashtable_new_full (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
+mono_conc_hashtable_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
 {
-       MonoConcurrentHashTable *res = mono_conc_hashtable_new (mutex, hash_func, key_equal_func);
+       MonoConcurrentHashTable *res = mono_conc_hashtable_new (hash_func, key_equal_func);
        res->key_destroy_func = key_destroy_func;
        res->value_destroy_func = value_destroy_func;
        return res;
@@ -215,7 +213,9 @@ retry:
 }
 
 /**
- * mono_conc_hashtable_remove
+ * mono_conc_hashtable_remove:
+ *
+ * Remove a value from the hashtable. Requires external locking
  *
  * @Returns the old value if key is already present or null
  */
@@ -229,7 +229,6 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
        g_assert (key != NULL && key != TOMBSTONE);
 
        hash = mix_hash (hash_table->hash_func (key));
-       mono_mutex_lock (hash_table->mutex);
 
        table = (conc_table*)hash_table->table;
        kvs = table->kvs;
@@ -239,7 +238,6 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
        if (!hash_table->equal_func) {
                for (;;) {
                        if (!kvs [i].key) {
-                               mono_mutex_unlock (hash_table->mutex);
                                return NULL; /*key not found*/
                        }
 
@@ -249,7 +247,6 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
                                mono_memory_barrier ();
                                kvs [i].key = TOMBSTONE;
 
-                               mono_mutex_unlock (hash_table->mutex);
                                if (hash_table->key_destroy_func != NULL)
                                        (*hash_table->key_destroy_func) (key);
                                if (hash_table->value_destroy_func != NULL)
@@ -263,7 +260,6 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
                GEqualFunc equal = hash_table->equal_func;
                for (;;) {
                        if (!kvs [i].key) {
-                               mono_mutex_unlock (hash_table->mutex);
                                return NULL; /*key not found*/
                        }
 
@@ -274,7 +270,6 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
                                mono_memory_barrier ();
                                kvs [i].key = TOMBSTONE;
 
-                               mono_mutex_unlock (hash_table->mutex);
                                if (hash_table->key_destroy_func != NULL)
                                        (*hash_table->key_destroy_func) (old_key);
                                if (hash_table->value_destroy_func != NULL)
@@ -287,8 +282,9 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
        }
 }
 /**
- * mono_conc_hashtable_insert
- *
+ * mono_conc_hashtable_insert:
+ * 
+ * Insert a value into the hashtable. Requires external locking.
  * @Returns the old value if key is already present or null
  */
 gpointer
@@ -302,7 +298,6 @@ mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, g
        g_assert (value != NULL);
 
        hash = mix_hash (hash_table->hash_func (key));
-       mono_mutex_lock (hash_table->mutex);
 
        if (hash_table->element_count >= hash_table->overflow_count)
                expand_table (hash_table);
@@ -320,12 +315,10 @@ mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, g
                                mono_memory_barrier ();
                                kvs [i].key = key;
                                ++hash_table->element_count;
-                               mono_mutex_unlock (hash_table->mutex);
                                return NULL;
                        }
                        if (key == kvs [i].key) {
                                gpointer value = kvs [i].value;
-                               mono_mutex_unlock (hash_table->mutex);
                                return value;
                        }
                        i = (i + 1) & table_mask;
@@ -339,12 +332,10 @@ mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, g
                                mono_memory_barrier ();
                                kvs [i].key = key;
                                ++hash_table->element_count;
-                               mono_mutex_unlock (hash_table->mutex);
                                return NULL;
                        }
                        if (equal (key, kvs [i].key)) {
                                gpointer value = kvs [i].value;
-                               mono_mutex_unlock (hash_table->mutex);
                                return value;
                        }
                        i = (i + 1) & table_mask;
@@ -352,6 +343,11 @@ mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, g
        }
 }
 
+/**
+ * mono_conc_hashtable_foreach:
+ *
+ * Calls @func for each value in the hashtable. Requires external locking.
+ */
 void
 mono_conc_hashtable_foreach (MonoConcurrentHashTable *hash_table, GHFunc func, gpointer userdata)
 {
@@ -359,11 +355,9 @@ mono_conc_hashtable_foreach (MonoConcurrentHashTable *hash_table, GHFunc func, g
        conc_table *table = (conc_table*)hash_table->table;
        key_value_pair *kvs = table->kvs;
 
-  mono_mutex_lock (hash_table->mutex);
        for (i = 0; i < table->table_size; ++i) {
                if (kvs [i].key && kvs [i].key != TOMBSTONE) {
                        func (kvs [i].key, kvs [i].value, userdata);
                }
        }
-       mono_mutex_unlock (hash_table->mutex);
 }
index 91d4e1948b1c6706da1f46665c1ecef32ed5a7fb..a1d20f1b04e7695dafff1b4825eb9a3609dfa887 100644 (file)
@@ -17,8 +17,8 @@
 
 typedef struct _MonoConcurrentHashTable MonoConcurrentHashTable;
 
-MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func);
-MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new_full (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func);
+MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new (GHashFunc hash_func, GEqualFunc key_equal_func);
+MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func);
 MONO_API void mono_conc_hashtable_destroy (MonoConcurrentHashTable *hash_table);
 MONO_API gpointer mono_conc_hashtable_lookup (MonoConcurrentHashTable *hash_table, gpointer key);
 MONO_API gpointer mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, gpointer value);
index 33a821a198a9bd57851f752fb29a49cd3619b75d..82ee789dd1d02bf048e4fe48cf2c087ef3216f33 100644 (file)
@@ -350,8 +350,8 @@ typedef struct {
                : "x30", "memory"                       \
        );                                                              \
        __asm__ __volatile__( \
-               "adr %0, L0\n" \
-               "L0:\n" \
+               "adr %0, L0%=\n" \
+               "L0%=:\n"       \
                : "=r" (ctx.pc)         \
                :                                       \
                : "memory"                       \
@@ -368,6 +368,100 @@ typedef struct {
  * We might also want to add an additional field to propagate
  * the original context from the signal handler.
  */
+#ifdef __mono_ppc64__
+
+typedef struct {
+       gulong sc_ir;          // pc 
+       gulong sc_sp;          // r1
+       mgreg_t regs [32];
+       double fregs [32];
+} MonoContext;
+
+/* we have the stack pointer, not the base pointer in sigcontext */
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_ir = (gulong)ip; } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_sp = (gulong)bp; } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_sp = (gulong)sp; } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
+
+#define MONO_CONTEXT_GET_CURRENT(ctx)  \
+       __asm__ __volatile__(   \
+               "std 0, 0(%0)\n"        \
+               "std 1, 8(%0)\n"        \
+               "std 0, 8*0+16(%0)\n"   \
+               "std 1, 8*1+16(%0)\n"   \
+               "std 2, 8*2+16(%0)\n"   \
+               "std 3, 8*3+16(%0)\n"   \
+               "std 4, 8*4+16(%0)\n"   \
+               "std 5, 8*5+16(%0)\n"   \
+               "std 6, 8*6+16(%0)\n"   \
+               "std 7, 8*7+16(%0)\n"   \
+               "std 8, 8*8+16(%0)\n"   \
+               "std 9, 8*9+16(%0)\n"   \
+               "std 10, 8*10+16(%0)\n" \
+               "std 11, 8*11+16(%0)\n" \
+               "std 12, 8*12+16(%0)\n" \
+               "std 13, 8*13+16(%0)\n" \
+               "std 14, 8*14+16(%0)\n" \
+               "std 15, 8*15+16(%0)\n" \
+               "std 16, 8*16+16(%0)\n" \
+               "std 17, 8*17+16(%0)\n" \
+               "std 18, 8*18+16(%0)\n" \
+               "std 19, 8*19+16(%0)\n" \
+               "std 20, 8*20+16(%0)\n" \
+               "std 21, 8*21+16(%0)\n" \
+               "std 22, 8*22+16(%0)\n" \
+               "std 23, 8*23+16(%0)\n" \
+               "std 24, 8*24+16(%0)\n" \
+               "std 25, 8*25+16(%0)\n" \
+               "std 26, 8*26+16(%0)\n" \
+               "std 27, 8*27+16(%0)\n" \
+               "std 28, 8*28+16(%0)\n" \
+               "std 29, 8*29+16(%0)\n" \
+               "std 30, 8*30+16(%0)\n" \
+               "std 31, 8*31+16(%0)\n" \
+               "stfd 0, 8*0+8*32+16(%0)\n"     \
+               "stfd 1, 8*1+8*32+16(%0)\n"     \
+               "stfd 2, 8*2+8*32+16(%0)\n"     \
+               "stfd 3, 8*3+8*32+16(%0)\n"     \
+               "stfd 4, 8*4+8*32+16(%0)\n"     \
+               "stfd 5, 8*5+8*32+16(%0)\n"     \
+               "stfd 6, 8*6+8*32+16(%0)\n"     \
+               "stfd 7, 8*7+8*32+16(%0)\n"     \
+               "stfd 8, 8*8+8*32+16(%0)\n"     \
+               "stfd 9, 8*9+8*32+16(%0)\n"     \
+               "stfd 10, 8*10+8*32+16(%0)\n"   \
+               "stfd 11, 8*11+8*32+16(%0)\n"   \
+               "stfd 12, 8*12+8*32+16(%0)\n"   \
+               "stfd 13, 8*13+8*32+16(%0)\n"   \
+               "stfd 14, 8*14+8*32+16(%0)\n"   \
+               "stfd 15, 8*15+8*32+16(%0)\n"   \
+               "stfd 16, 8*16+8*32+16(%0)\n"   \
+               "stfd 17, 8*17+8*32+16(%0)\n"   \
+               "stfd 18, 8*18+8*32+16(%0)\n"   \
+               "stfd 19, 8*19+8*32+16(%0)\n"   \
+               "stfd 20, 8*20+8*32+16(%0)\n"   \
+               "stfd 21, 8*21+8*32+16(%0)\n"   \
+               "stfd 22, 8*22+8*32+16(%0)\n"   \
+               "stfd 23, 8*23+8*32+16(%0)\n"   \
+               "stfd 24, 8*24+8*32+16(%0)\n"   \
+               "stfd 25, 8*25+8*32+16(%0)\n"   \
+               "stfd 26, 8*26+8*32+16(%0)\n"   \
+               "stfd 27, 8*27+8*32+16(%0)\n"   \
+               "stfd 28, 8*28+8*32+16(%0)\n"   \
+               "stfd 29, 8*29+8*32+16(%0)\n"   \
+               "stfd 30, 8*30+8*32+16(%0)\n"   \
+               "stfd 31, 8*31+8*32+16(%0)\n"   \
+               : : "r" (&(ctx))        \
+               : "memory"                      \
+       )
+
+#define MONO_ARCH_HAS_MONO_CONTEXT 1
+
+#else 
+
 typedef struct {
        gulong sc_ir;          // pc 
        gulong sc_sp;          // r1
@@ -384,6 +478,7 @@ typedef struct {
 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
+#endif
 
 #elif defined(__sparc__) || defined(sparc) /* defined(__mono_ppc__) */
 
index 209b9e6f0ca0e45437b54ba6373cbda941806d3a..ee88665ae6c185ceaf09da5d3b9ba6edf887d5d6 100644 (file)
@@ -15,6 +15,7 @@ typedef enum {
        MONO_TRACE_AOT                  = (1<<5),
        MONO_TRACE_SECURITY             = (1<<6),
        MONO_TRACE_THREADPOOL           = (1<<7),
+       MONO_TRACE_IO_THREADPOOL        = (1<<8),
        MONO_TRACE_ALL                  = MONO_TRACE_ASSEMBLY |
                                          MONO_TRACE_TYPE |
                                          MONO_TRACE_DLLIMPORT |
@@ -22,7 +23,8 @@ typedef enum {
                                          MONO_TRACE_CONFIG |
                                          MONO_TRACE_AOT |
                                          MONO_TRACE_SECURITY |
-                                         MONO_TRACE_THREADPOOL
+                                         MONO_TRACE_THREADPOOL |
+                                         MONO_TRACE_IO_THREADPOOL
 } MonoTraceMask;
 
 void 
index 54bf4db6f629e4f8f90f4e0d26ca9136950f2b39..0b2c8a7f69b4e070157089cf25bb0d0b42a68a8f 100644 (file)
@@ -213,10 +213,10 @@ mono_trace_set_mask_string (const char *value)
        const char *tok;
        guint32 flags = 0;
 
-       const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "all", NULL};
+       const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "all", NULL};
        const MonoTraceMask     valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
                                                 MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_SECURITY,
-                                                MONO_TRACE_THREADPOOL, MONO_TRACE_ALL };
+                                                MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_ALL };
 
        if(!value)
                return;
index d821f3c5e32b167c5b8c868668f0cb931da592da..cfeb19d31b9f5960698c4925ba8ecb13e711c757 100644 (file)
@@ -19,7 +19,8 @@ typedef enum {
        FRAME_TYPE_DEBUGGER_INVOKE = 1,
        /* Frame for transitioning to native code */
        FRAME_TYPE_MANAGED_TO_NATIVE = 2,
-       FRAME_TYPE_SENTINEL = 3
+       FRAME_TYPE_TRAMPOLINE = 3,
+       FRAME_TYPE_NUM = 4
 } MonoStackFrameType;
 
 typedef enum {
diff --git a/mono/utils/mono-threads-api.h b/mono/utils/mono-threads-api.h
new file mode 100644 (file)
index 0000000..f94fd66
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * mono-threads-api.h: Low level access to thread state.
+ *
+ * Author:
+ *     Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2015 Xamarin
+ */
+
+#ifndef __MONO_THREADS_API_H__
+#define __MONO_THREADS_API_H__
+
+#include <mono/utils/mono-publib.h>
+MONO_BEGIN_DECLS
+
+/*
+>>>> WARNING WARNING WARNING <<<<
+
+This API is experimental. It will eventually be required to properly use the rest of the raw-omp embedding API.
+*/
+
+/* Don't use those directly, use the MONO_(BEGIN|END)_EFRAME */
+MONO_API void* mono_threads_enter_gc_unsafe_region (void);
+MONO_API void mono_threads_exit_gc_unsafe_region (void *region_cookie);
+
+/*
+Use those macros to limit regions of code that interact with managed memory or use the embedding API.
+This will put the current thread in GC Unsafe mode.
+
+For further explanation of what can and can't be done in GC unsafe mode:
+http://www.mono-project.com/docs/advanced/runtime/docs/coop-suspend/#gc-unsafe-mode
+
+*/
+#define MONO_BEGIN_EFRAME { void *__region_cookie = mono_threads_enter_gc_unsafe_region ();
+#define MONO_END_EFRAME mono_threads_exit_gc_unsafe_region (__region_cookie); }
+
+
+MONO_END_DECLS
+
+#endif /* __MONO_LOGGER_H__ */
index b44719109ffc277ad377942a4b219b21a92d8408..4c9826aa767dd4ce4c61080dfc785706744cf40f 100644 (file)
@@ -1,4 +1,4 @@
-/*
+ /*
  * mono-threads.c: Coop threading
  *
  * Author:
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-time.h>
+#include <mono/utils/mono-counters.h>
+
+#ifdef TARGET_OSX
+#include <mono/utils/mach-support.h>
+#endif
 
 #ifdef USE_COOP_BACKEND
 
 volatile size_t mono_polling_required;
 
+static int coop_reset_blocking_count, coop_try_blocking_count, coop_do_blocking_count, coop_do_polling_count, coop_save_count;
+
 void
 mono_threads_state_poll (void)
 {
        MonoThreadInfo *info;
+       ++coop_do_polling_count;
 
        info = mono_thread_info_current_unchecked ();
        if (!info)
@@ -35,7 +43,8 @@ mono_threads_state_poll (void)
        if (!(info->thread_state & (STATE_ASYNC_SUSPEND_REQUESTED | STATE_SELF_SUSPEND_REQUESTED)))
                return;
 
-       g_assert (mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL));
+       ++coop_save_count;
+       mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
 
        /* commit the saved state and notify others if needed */
        switch (mono_threads_transition_state_poll (info)) {
@@ -55,6 +64,7 @@ void*
 mono_threads_prepare_blocking (void)
 {
        MonoThreadInfo *info;
+       ++coop_do_blocking_count;
 
        info = mono_thread_info_current_unchecked ();
        /* If the thread is not attached, it doesn't make sense prepare for suspend. */
@@ -64,11 +74,8 @@ mono_threads_prepare_blocking (void)
        }
 
 retry:
-       /*The JIT might not be able to save*/
-       if (!mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL)) {
-               THREADS_SUSPEND_DEBUG ("PREPARE-BLOCKING failed %p to save thread state\n", mono_thread_info_get_tid (info));
-               return NULL;
-       }
+       ++coop_save_count;
+       mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
 
        switch (mono_threads_transition_do_blocking (info)) {
        case DoBlockingContinue:
@@ -117,6 +124,7 @@ void*
 mono_threads_reset_blocking_start (void)
 {
        MonoThreadInfo *info = mono_thread_info_current_unchecked ();
+       ++coop_reset_blocking_count;
 
        /* If the thread is not attached, it doesn't make sense prepare for suspend. */
        if (!info || !mono_thread_info_is_live (info))
@@ -156,6 +164,7 @@ void*
 mono_threads_try_prepare_blocking (void)
 {
        MonoThreadInfo *info;
+       ++coop_try_blocking_count;
 
        info = mono_thread_info_current_unchecked ();
        /* If the thread is not attached, it doesn't make sense prepare for suspend. */
@@ -165,11 +174,8 @@ mono_threads_try_prepare_blocking (void)
        }
 
 retry:
-       /*The JIT might not be able to save*/
-       if (!mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL)) {
-               THREADS_SUSPEND_DEBUG ("PREPARE-TRY-BLOCKING failed %p to save thread state\n", mono_thread_info_get_tid (info));
-               return NULL;
-       }
+       ++coop_save_count;
+       mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
 
        switch (mono_threads_transition_do_blocking (info)) {
        case DoBlockingContinue:
@@ -235,18 +241,31 @@ mono_threads_core_needs_abort_syscall (void)
 void
 mono_threads_init_platform (void)
 {
+       mono_counters_register ("Coop Reset Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_reset_blocking_count);
+       mono_counters_register ("Coop Try Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_try_blocking_count);
+       mono_counters_register ("Coop Do Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_do_blocking_count);
+       mono_counters_register ("Coop Do Polling", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_do_polling_count);
+       mono_counters_register ("Coop Save Count", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_save_count);
        //See the above for what's wrong here.
 }
 
 void
 mono_threads_platform_free (MonoThreadInfo *info)
 {
+#ifdef TARGET_OSX
+       mach_port_deallocate (current_task (), info->native_handle);
+#endif
+
        //See the above for what's wrong here.
 }
 
 void
 mono_threads_platform_register (MonoThreadInfo *info)
 {
+#ifdef TARGET_OSX
+       info->native_handle = mach_thread_self ();
+#endif
+
        //See the above for what's wrong here.
 }
 
@@ -262,5 +281,29 @@ mono_threads_core_end_global_suspend (void)
        mono_polling_required = 0;
 }
 
+void*
+mono_threads_enter_gc_unsafe_region (void)
+{
+       return mono_threads_reset_blocking_start ();
+}
+
+void
+mono_threads_exit_gc_unsafe_region (void *regions_cookie)
+{
+       mono_threads_reset_blocking_end (regions_cookie);
+}
+
+#else
+
+void*
+mono_threads_enter_gc_unsafe_region (void)
+{
+       return NULL;
+}
+
+void
+mono_threads_exit_gc_unsafe_region (void *regions_cookie)
+{
+}
 
 #endif
\ No newline at end of file
index 6eca0266dcfb897f4fbef80bdfd1bc58f9ecdb01..88ae40aee8769cbf4005a79d8196d5ceaac6d88e 100644 (file)
@@ -17,7 +17,7 @@
 /* Runtime consumable API */
 
 #define MONO_SUSPEND_CHECK() do {      \
-       if (G_UNLIKELY (mono_threads_polling_required)) mono_threads_state_poll ();     \
+       if (G_UNLIKELY (mono_polling_required)) mono_threads_state_poll ();     \
 } while (0);
 
 #define MONO_PREPARE_BLOCKING  \
@@ -46,8 +46,6 @@
 
 /* Internal API */
 
-extern volatile size_t mono_threads_polling_required;
-
 void mono_threads_state_poll (void);
 void* mono_threads_prepare_blocking (void);
 void mono_threads_finish_blocking (void* cookie);
@@ -59,11 +57,11 @@ void* mono_threads_try_prepare_blocking (void);
 void mono_threads_finish_try_blocking (void* cookie);
 
 /* JIT specific interface */
-extern volatile size_t mono_polling_required ;
+extern volatile size_t mono_polling_required;
 
 #else
 
-#define MONO_SUSPEND_CHECK do {        } while (0);
+#define MONO_SUSPEND_CHECK() do {      } while (0);
 #define MONO_PREPARE_BLOCKING {
 #define MONO_FINISH_BLOCKING }
 #define MONO_PREPARE_RESET_BLOCKING {
index fc884e7a05584787d813ff2b241012da9a61eaa1..fbb78b498fa7d252b59e3b236bfa6772676d9a35 100644 (file)
@@ -31,12 +31,6 @@ mono_threads_init_platform (void)
        mono_threads_init_dead_letter ();
 }
 
-void
-mono_threads_core_interrupt (MonoThreadInfo *info)
-{
-       thread_abort (info->native_handle);
-}
-
 void
 mono_threads_core_abort_syscall (MonoThreadInfo *info)
 {
index e9ca1415c04eee3f37dfd855b451b738d72f7ab6..3e2790024a80fa4ba75f7df33426d51ad7a7f12b 100644 (file)
@@ -71,7 +71,7 @@ inner_start_thread (void *arg)
        start_info->handle = handle;
 
        info = mono_thread_info_attach (&result);
-       MONO_PREPARE_BLOCKING
+       MONO_PREPARE_BLOCKING;
 
        info->runtime_thread = TRUE;
        info->handle = handle;
@@ -92,7 +92,7 @@ inner_start_thread (void *arg)
                MONO_SEM_DESTROY (&info->create_suspended_sem);
        }
 
-       MONO_FINISH_BLOCKING
+       MONO_FINISH_BLOCKING;
        /* Run the actual main function of the thread */
        result = start_func (t_arg);
 
@@ -145,10 +145,13 @@ mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer
                return NULL;
        }
 
+       MONO_TRY_BLOCKING;
        /* Wait until the thread register itself in various places */
        while (MONO_SEM_WAIT (&(start_info.registered)) != 0) {
                /*if (EINTR != errno) ABORT("sem_wait failed"); */
        }
+       MONO_FINISH_TRY_BLOCKING;
+
        MONO_SEM_DESTROY (&(start_info.registered));
 
        if (out_tid)
@@ -236,30 +239,6 @@ mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
        return handle;
 }
 
-gpointer
-mono_threads_core_prepare_interrupt (HANDLE thread_handle)
-{
-       return wapi_prepare_interrupt_thread (thread_handle);
-}
-
-void
-mono_threads_core_finish_interrupt (gpointer wait_handle)
-{
-       wapi_finish_interrupt_thread (wait_handle);
-}
-
-void
-mono_threads_core_self_interrupt (void)
-{
-       wapi_self_interrupt ();
-}
-
-void
-mono_threads_core_clear_interruption (void)
-{
-       wapi_clear_interruption ();
-}
-
 int
 mono_threads_pthread_kill (MonoThreadInfo *info, int signum)
 {
index 9f5792c1d9c1d1d6c9da640b2807920440729006..bf38fd4f24415b797d3551c9ad5036962241ccd9 100644 (file)
@@ -5,6 +5,7 @@
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/atomic.h>
+#include <mono/utils/checked-build.h>
 
 #include <errno.h>
 
@@ -89,6 +90,8 @@ trace_state_change (const char *transition, MonoThreadInfo *info, int cur_raw_st
                state_name (next_state),
                get_thread_suspend_count (cur_raw_state),
                get_thread_suspend_count (cur_raw_state) + suspend_count_delta);
+
+       CHECKED_BUILD_THREAD_TRANSITION (transition, info, get_thread_state (cur_raw_state), get_thread_suspend_count (cur_raw_state), next_state, suspend_count_delta);
 }
 
 /*
@@ -187,7 +190,7 @@ STATE_BLOCKING_AND_SUSPENDED: Self suspension cannot be started when the thread
 If this turns to be an issue we can introduce a new suspend request state for when both have been requested.
 */
        default:
-               g_error ("Cannot transition thread %p from %s with SUSPEND_REQUEST", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with SUSPEND_REQUEST", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -248,7 +251,7 @@ The expected behavior is that the target should poll its state very soon so the
 STATE_ASYNC_SUSPEND_REQUESTED: Since there can only be one async suspend in progress and it must finish, it should not be possible to witness this.
 */
        default:
-               g_error ("Cannot transition thread %p from %s with ASYNC_SUSPEND_REQUESTED", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with ASYNC_SUSPEND_REQUESTED", mono_thread_info_get_tid (info), state_name (cur_state));
        }
        return (MonoRequestAsyncSuspendResult) FALSE;
 }
@@ -297,7 +300,7 @@ STATE_BLOCKING:
 STATE_BLOCKING_AND_SUSPENDED: Pool is a local state transition. No VM activities are allowed while in blocking mode.
 */
        default:
-               g_error ("Cannot transition thread %p from %s with STATE_POLL", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with STATE_POLL", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -397,7 +400,7 @@ If this turns to be a problem we should either implement [2] or make this an inv
 
 */
        default:
-               g_error ("Cannot transition thread %p from %s with REQUEST_RESUME", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with REQUEST_RESUME", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -433,7 +436,7 @@ STATE_SELF_SUSPEND_REQUESTED: When self suspend and async suspend happen togethe
 STATE_BLOCKING: Async suspend only begins if a transition to async suspend requested happened. Blocking would have put us into blocking with positive suspend count if it raced with async finish.
 */
        default:
-               g_error ("Cannot transition thread %p from %s with FINISH_ASYNC_SUSPEND", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with FINISH_ASYNC_SUSPEND", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -477,7 +480,7 @@ STATE_BLOCKING_AND_SUSPENDED
 STATE_SELF_SUSPEND_REQUESTED: All those are invalid end states of a sucessfull finish async suspend
 */
        default:
-               g_error ("Cannot transition thread %p from %s with COMPENSATE_FINISH_ASYNC_SUSPEND", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with COMPENSATE_FINISH_ASYNC_SUSPEND", mono_thread_info_get_tid (info), state_name (cur_state));
 
        }
 }
@@ -522,7 +525,7 @@ STATE_BLOCKING:
 STATE_BLOCKING_AND_SUSPENDED: Blocking is not nestabled
 */
        default:
-               g_error ("Cannot transition thread %p from %s with DO_BLOCKING", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with DO_BLOCKING", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -570,7 +573,7 @@ STATE_SELF_SUSPEND_REQUESTED: A blocking operation must not be done while trying
 STATE_BLOCKING_AND_SUSPENDED: This an exit state of done blocking
 */
        default:
-               g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -620,7 +623,7 @@ STATE_SELF_SUSPEND_REQUESTED: A blocking operation must not be done while trying
 STATE_BLOCKING_AND_SUSPENDED: This is an exit state of done blocking, can't happen here.
 */
        default:
-               g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", info, state_name (cur_state));
+               g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", mono_thread_info_get_tid (info), state_name (cur_state));
        }
 }
 
@@ -691,3 +694,9 @@ mono_thread_info_current_state (MonoThreadInfo *info)
 {
        return get_thread_state (info->thread_state);
 }
+
+const char*
+mono_thread_state_name (int state)
+{
+       return state_name (state);
+}
old mode 100755 (executable)
new mode 100644 (file)
index 9f3581e..9e59810
@@ -395,26 +395,4 @@ mono_threads_core_set_name (MonoNativeThreadId tid, const char *name)
 #endif
 }
 
-
-gpointer
-mono_threads_core_prepare_interrupt (HANDLE thread_handle)
-{
-       return NULL;
-}
-
-void
-mono_threads_core_finish_interrupt (gpointer wait_handle)
-{
-}
-
-void
-mono_threads_core_self_interrupt (void)
-{
-}
-
-void
-mono_threads_core_clear_interruption (void)
-{
-}
-
 #endif
index 366f09468e952c5882802b4dd0edf07d8655bd73..4b2bcdc6937683efc045e2e05bec08cb70942974 100644 (file)
@@ -149,7 +149,7 @@ dump_threads (void)
        MonoThreadInfo *info;
        MonoThreadInfo *cur = mono_thread_info_current ();
 
-       MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2)\n");
+       MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2, * means any number)\n");
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x0\t- starting (GOOD, unless the thread is running managed code)\n");
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x1\t- running (BAD, unless it's the gc thread)\n");
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x2\t- detached (GOOD, unless the thread is running managed code)\n");
@@ -157,7 +157,7 @@ dump_threads (void)
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?04\t- self suspended (GOOD)\n");
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?05\t- async suspend requested (BAD)\n");
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?06\t- self suspend requested (BAD)\n");
-       MOSTLY_ASYNC_SAFE_PRINTF ("\t0x07\t- blocking (GOOD)\n");
+       MOSTLY_ASYNC_SAFE_PRINTF ("\t0x*07\t- blocking (GOOD)\n");
        MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?08\t- blocking with pending suspend (GOOD)\n");
 
        FOREACH_THREAD_SAFE (info) {
@@ -357,14 +357,7 @@ unregister_thread (void *arg)
        if (threads_callbacks.thread_detach)
                threads_callbacks.thread_detach (info);
 
-       /*
-       Since the thread info lock is taken from within blocking sections, we can't check from there, so it must be done here.
-       This ensures that we won't lose any suspend requests as a suspend initiator must hold the lock.
-       Once we're holding the suspend lock, no threads can suspend us and once we unregister, no thread can find us. 
-       */
-       MONO_PREPARE_BLOCKING
        mono_thread_info_suspend_lock ();
-       MONO_FINISH_BLOCKING
 
        /*
        Now perform the callback that must be done under locks.
@@ -681,7 +674,7 @@ mono_thread_info_end_self_suspend (void)
                return;
        THREADS_SUSPEND_DEBUG ("FINISH SELF SUSPEND OF %p\n", info);
 
-       g_assert (mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL));
+       mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
 
        /* commit the saved state and notify others if needed */
        switch (mono_threads_transition_state_poll (info)) {
@@ -884,6 +877,7 @@ mono_thread_info_safe_suspend_and_run (MonoNativeThreadId id, gboolean interrupt
        /*FIXME: unify this with self-suspend*/
        g_assert (id != mono_native_thread_id_get ());
 
+       /* This can block during stw */
        mono_thread_info_suspend_lock ();
        mono_threads_begin_global_suspend ();
 
@@ -968,7 +962,9 @@ STW to make sure no unsafe pending suspend is in progress.
 void
 mono_thread_info_suspend_lock (void)
 {
+       MONO_TRY_BLOCKING;
        MONO_SEM_WAIT_UNITERRUPTIBLE (&global_suspend_semaphore);
+       MONO_FINISH_TRY_BLOCKING;
 }
 
 void
@@ -1153,42 +1149,204 @@ mono_thread_info_set_name (MonoNativeThreadId tid, const char *name)
        mono_threads_core_set_name (tid, name);
 }
 
+#define INTERRUPT_STATE ((MonoThreadInfoInterruptToken*) (size_t) -1)
+
+struct _MonoThreadInfoInterruptToken {
+       void (*callback) (gpointer data);
+       gpointer data;
+};
+
 /*
- * mono_thread_info_prepare_interrupt:
+ * mono_thread_info_install_interrupt: install an interruption token for the current thread.
  *
- *   See wapi_prepare_interrupt ().
+ *  - @callback: must be able to be called from another thread and always cancel the wait
+ *  - @data: passed to the callback
+ *  - @interrupted: will be set to TRUE if a token is already installed, FALSE otherwise
+ *     if set to TRUE, it must mean that the thread is in interrupted state
  */
-gpointer
-mono_thread_info_prepare_interrupt (HANDLE thread_handle)
+void
+mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted)
 {
-       return mono_threads_core_prepare_interrupt (thread_handle);
+       MonoThreadInfo *info;
+       MonoThreadInfoInterruptToken *previous_token, *token;
+
+       g_assert (callback);
+
+       g_assert (interrupted);
+       *interrupted = FALSE;
+
+       info = mono_thread_info_current ();
+       g_assert (info);
+
+       /* The memory of this token can be freed at 2 places:
+        *  - if the token is not interrupted: it will be freed in uninstall, as info->interrupt_token has not been replaced
+        *     by the INTERRUPT_STATE flag value, and it still contains the pointer to the memory location
+        *  - if the token is interrupted: it will be freed in finish, as the token is now owned by the prepare/finish
+        *     functions, and info->interrupt_token does not contains a pointer to the memory anymore */
+       token = g_new0 (MonoThreadInfoInterruptToken, 1);
+       token->callback = callback;
+       token->data = data;
+
+       previous_token = InterlockedCompareExchangePointer ((gpointer*) &info->interrupt_token, token, NULL);
+
+       if (previous_token) {
+               if (previous_token != INTERRUPT_STATE)
+                       g_error ("mono_thread_info_install_interrupt: previous_token should be INTERRUPT_STATE (%p), but it was %p", INTERRUPT_STATE, previous_token);
+
+               g_free (token);
+
+               *interrupted = TRUE;
+       }
+
+       THREADS_INTERRUPT_DEBUG ("interrupt install    tid %p token %p previous_token %p interrupted %s\n",
+               mono_thread_info_get_tid (info), token, previous_token, *interrupted ? "TRUE" : "FALSE");
 }
 
 void
-mono_thread_info_finish_interrupt (gpointer wait_handle)
+mono_thread_info_uninstall_interrupt (gboolean *interrupted)
+{
+       MonoThreadInfo *info;
+       MonoThreadInfoInterruptToken *previous_token;
+
+       g_assert (interrupted);
+       *interrupted = FALSE;
+
+       info = mono_thread_info_current ();
+       g_assert (info);
+
+       previous_token = InterlockedExchangePointer ((gpointer*) &info->interrupt_token, NULL);
+
+       /* only the installer can uninstall the token */
+       g_assert (previous_token);
+
+       if (previous_token == INTERRUPT_STATE) {
+               /* if it is interrupted, then it is going to be freed in finish interrupt */
+               *interrupted = TRUE;
+       } else {
+               g_free (previous_token);
+       }
+
+       THREADS_INTERRUPT_DEBUG ("interrupt uninstall  tid %p previous_token %p interrupted %s\n",
+               mono_thread_info_get_tid (info), previous_token, *interrupted ? "TRUE" : "FALSE");
+}
+
+static MonoThreadInfoInterruptToken*
+set_interrupt_state (MonoThreadInfo *info)
+{
+       MonoThreadInfoInterruptToken *token, *previous_token;
+
+       g_assert (info);
+
+       /* Atomically obtain the token the thread is
+       * waiting on, and change it to a flag value. */
+
+       do {
+               previous_token = info->interrupt_token;
+
+               /* Already interrupted */
+               if (previous_token == INTERRUPT_STATE) {
+                       token = NULL;
+                       break;
+               }
+
+               token = previous_token;
+       } while (InterlockedCompareExchangePointer ((gpointer*) &info->interrupt_token, INTERRUPT_STATE, previous_token) != previous_token);
+
+       return token;
+}
+
+/*
+ * mono_thread_info_prepare_interrupt:
+ *
+ * The state of the thread info interrupt token is set to 'interrupted' which means that :
+ *  - if the thread calls one of the WaitFor functions, the function will return with
+ *     WAIT_IO_COMPLETION instead of waiting
+ *  - if the thread was waiting when this function was called, the wait will be broken
+ *
+ * It is possible that the wait functions return WAIT_IO_COMPLETION, but the target thread
+ * didn't receive the interrupt signal yet, in this case it should call the wait function
+ * again. This essentially means that the target thread will busy wait until it is ready to
+ * process the interruption.
+ */
+MonoThreadInfoInterruptToken*
+mono_thread_info_prepare_interrupt (MonoThreadInfo *info)
 {
-       mono_threads_core_finish_interrupt (wait_handle);
+       MonoThreadInfoInterruptToken *token;
+
+       token = set_interrupt_state (info);
+
+       THREADS_INTERRUPT_DEBUG ("interrupt prepare    tid %p token %p\n",
+               mono_thread_info_get_tid (info), token);
+
+       return token;
 }
 
 void
-mono_thread_info_interrupt (HANDLE thread_handle)
+mono_thread_info_finish_interrupt (MonoThreadInfoInterruptToken *token)
 {
-       gpointer wait_handle;
+       THREADS_INTERRUPT_DEBUG ("interrupt finish     token %p\n", token);
+
+       if (token == NULL)
+               return;
+
+       g_assert (token->callback);
+
+       token->callback (token->data);
 
-       wait_handle = mono_thread_info_prepare_interrupt (thread_handle);
-       mono_thread_info_finish_interrupt (wait_handle);
+       g_free (token);
 }
-       
+
 void
 mono_thread_info_self_interrupt (void)
 {
-       mono_threads_core_self_interrupt ();
+       MonoThreadInfo *info;
+       MonoThreadInfoInterruptToken *token;
+
+       info = mono_thread_info_current ();
+       g_assert (info);
+
+       token = set_interrupt_state (info);
+       g_assert (!token);
+
+       THREADS_INTERRUPT_DEBUG ("interrupt self       tid %p\n",
+               mono_thread_info_get_tid (info));
+}
+
+/* Clear the interrupted flag of the current thread, set with
+ * mono_thread_info_self_interrupt, so it can wait again */
+void
+mono_thread_info_clear_self_interrupt ()
+{
+       MonoThreadInfo *info;
+       MonoThreadInfoInterruptToken *previous_token;
+
+       info = mono_thread_info_current ();
+       g_assert (info);
+
+       previous_token = InterlockedCompareExchangePointer ((gpointer*) &info->interrupt_token, NULL, INTERRUPT_STATE);
+       g_assert (previous_token == NULL || previous_token == INTERRUPT_STATE);
+
+       THREADS_INTERRUPT_DEBUG ("interrupt clear self tid %p previous_token %p\n", mono_thread_info_get_tid (info), previous_token);
+}
+
+gboolean
+mono_thread_info_is_interrupt_state (MonoThreadInfo *info)
+{
+       g_assert (info);
+       return InterlockedReadPointer ((gpointer*) &info->interrupt_token) == INTERRUPT_STATE;
 }
 
 void
-mono_thread_info_clear_interruption (void)
+mono_thread_info_describe_interrupt_token (MonoThreadInfo *info, GString *text)
 {
-       mono_threads_core_clear_interruption ();
+       g_assert (info);
+
+       if (!InterlockedReadPointer ((gpointer*) &info->interrupt_token))
+               g_string_append_printf (text, "not waiting");
+       else if (InterlockedReadPointer ((gpointer*) &info->interrupt_token) == INTERRUPT_STATE)
+               g_string_append_printf (text, "interrupted state");
+       else
+               g_string_append_printf (text, "waiting");
 }
 
 /* info must be self or be held in a hazard pointer. */
index edbf934ac9bf7321a524a47459231121c00d9f40..003b4d2f3397714845abbc9c24b8c25a81e41052 100644 (file)
@@ -16,6 +16,7 @@
 #include <mono/utils/mono-mutex.h>
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/mono-threads-coop.h>
+#include <mono/utils/mono-threads-api.h>
 
 #include <glib.h>
 #include <config.h>
@@ -117,6 +118,12 @@ and reduce the number of casts drastically.
 #define THREADS_STATE_MACHINE_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
 #endif
 
+#if 1
+#define THREADS_INTERRUPT_DEBUG(...)
+#else
+#define THREADS_INTERRUPT_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
+#endif
+
 /* If this is defined, use the signals backed on Mach. Debug only as signals can't be made usable on OSX. */
 // #define USE_SIGNALS_ON_MACH
 
@@ -170,6 +177,8 @@ typedef enum {
        MONO_SERVICE_REQUEST_SAMPLE = 1,
 } MonoAsyncJob;
 
+typedef struct _MonoThreadInfoInterruptToken MonoThreadInfoInterruptToken;
+
 typedef struct {
        MonoLinkedListSetNode node;
        guint32 small_id; /*Used by hazard pointers */
@@ -243,6 +252,8 @@ typedef struct {
        volatile gint32 service_requests;
 
        void *jit_data;
+
+       MonoThreadInfoInterruptToken *interrupt_token;
 } MonoThreadInfo;
 
 typedef struct {
@@ -270,6 +281,7 @@ typedef struct {
        void (*setup_async_callback) (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data);
        gboolean (*thread_state_init_from_sigctx) (MonoThreadUnwindState *state, void *sigctx);
        gboolean (*thread_state_init_from_handle) (MonoThreadUnwindState *tctx, MonoThreadInfo *info);
+       void (*thread_state_init) (MonoThreadUnwindState *tctx);
 } MonoThreadInfoRuntimeCallbacks;
 
 //Not using 0 and 1 to ensure callbacks are not returning bad data
@@ -401,20 +413,29 @@ mono_thread_info_exit (void);
 HANDLE
 mono_thread_info_open_handle (void);
 
-gpointer
-mono_thread_info_prepare_interrupt (HANDLE thread_handle);
+void
+mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted);
 
 void
-mono_thread_info_finish_interrupt (gpointer wait_handle);
+mono_thread_info_uninstall_interrupt (gboolean *interrupted);
+
+MonoThreadInfoInterruptToken*
+mono_thread_info_prepare_interrupt (THREAD_INFO_TYPE *info);
 
 void
-mono_thread_info_interrupt (HANDLE thread_handle);
+mono_thread_info_finish_interrupt (MonoThreadInfoInterruptToken *token);
 
 void
 mono_thread_info_self_interrupt (void);
 
 void
-mono_thread_info_clear_interruption (void);
+mono_thread_info_clear_self_interrupt (void);
+
+gboolean
+mono_thread_info_is_interrupt_state (THREAD_INFO_TYPE *info);
+
+void
+mono_thread_info_describe_interrupt_token (THREAD_INFO_TYPE *info, GString *text);
 
 gboolean
 mono_thread_info_is_live (THREAD_INFO_TYPE *info);
@@ -457,7 +478,6 @@ gboolean mono_threads_core_suspend (THREAD_INFO_TYPE *info, gboolean interrupt_k
 gboolean mono_threads_core_resume (THREAD_INFO_TYPE *info);
 void mono_threads_platform_register (THREAD_INFO_TYPE *info); //ok
 void mono_threads_platform_free (THREAD_INFO_TYPE *info);
-void mono_threads_core_interrupt (THREAD_INFO_TYPE *info);
 void mono_threads_core_abort_syscall (THREAD_INFO_TYPE *info);
 gboolean mono_threads_core_needs_abort_syscall (void);
 HANDLE mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid);
@@ -523,10 +543,6 @@ void mono_threads_core_unregister (THREAD_INFO_TYPE *info);
 HANDLE mono_threads_core_open_handle (void);
 HANDLE mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
 void mono_threads_core_set_name (MonoNativeThreadId tid, const char *name);
-gpointer mono_threads_core_prepare_interrupt (HANDLE thread_handle);
-void mono_threads_core_finish_interrupt (gpointer wait_handle);
-void mono_threads_core_self_interrupt (void);
-void mono_threads_core_clear_interruption (void);
 
 MonoNativeThreadId mono_native_thread_id_get (void);
 
@@ -617,6 +633,7 @@ gboolean mono_thread_info_is_running (THREAD_INFO_TYPE *info);
 gboolean mono_thread_info_is_live (THREAD_INFO_TYPE *info);
 int mono_thread_info_suspend_count (THREAD_INFO_TYPE *info);
 int mono_thread_info_current_state (THREAD_INFO_TYPE *info);
+const char* mono_thread_state_name (int state);
 
 gboolean mono_thread_info_in_critical_location (THREAD_INFO_TYPE *info);
 gboolean mono_thread_info_begin_suspend (THREAD_INFO_TYPE *info, gboolean interrupt_kernel);
index 6954d751d5eb0c4f47b9f05622a92e00a9609d7a..a8b3ce55cce59f500ebfdf52e5bc6da651d8350a 100644 (file)
@@ -451,7 +451,7 @@ typedef
 
 #if defined(PLAT_amd64_win64) && !defined(__GNUC__)
 
-#error Unsupported compiler.
+//#error Unsupported compiler.
 
 #endif /* PLAT_amd64_win64 */
 
index b1692556f80b275d93911a9097be4e230f06f122..b3d0229f79d09827dabf9277216c18ab9caae03a 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
index 4b2af22d19036e17be43016de27653b2d5f04976..001463f7af21b3eadd9fc8e0a0516b34bb01a61a 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
   </PropertyGroup>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <SuppressStartupBanner>true</SuppressStartupBanner>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <SuppressStartupBanner>true</SuppressStartupBanner>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <SuppressStartupBanner>true</SuppressStartupBanner>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <SubSystem>Console</SubSystem>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <SuppressStartupBanner>true</SuppressStartupBanner>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <SubSystem>Console</SubSystem>\r
   <ItemGroup>\r
     <ProjectReference Include="eglib.vcxproj">\r
       <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index d3dd9ffd2fa8c2687bcf7a2b92fc9837c9e27871..2be0904f02ff1167dd55961a015e7ff56cc5b356 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\lib\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
index 925a6158311bc2b4253c34945cc98c3a90759464..026306597d62025b81fb104747cd27bcd478c0b3 100644 (file)
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">monosgen-2.0</TargetName>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">mono-2.0</TargetName>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">monosgen-2.0</TargetName>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">\r
     <PreBuildEvent>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
     <PreBuildEvent>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">\r
     <PreBuildEvent>\r
     <Link>\r
       <AdditionalDependencies>libgc.lib;libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
-      <ModuleDefinitionFile>monosgen64.def</ModuleDefinitionFile>\r
+      <ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <PreBuildEvent>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+      <PrecompiledHeaderOutputFile>\r
+      </PrecompiledHeaderOutputFile>\r
       <CompileAs>CompileAsC</CompileAs>\r
     </ClCompile>\r
     <ResourceCompile>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">\r
     <PreBuildEvent>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+      <PrecompiledHeaderOutputFile>\r
+      </PrecompiledHeaderOutputFile>\r
       <CompileAs>CompileAsC</CompileAs>\r
     </ClCompile>\r
     <ResourceCompile>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libgc.lib;libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
     <PreBuildEvent>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+      <PrecompiledHeaderOutputFile>\r
+      </PrecompiledHeaderOutputFile>\r
       <CompileAs>CompileAsC</CompileAs>\r
     </ClCompile>\r
     <ResourceCompile>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">\r
     <PreBuildEvent>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+      <PrecompiledHeaderOutputFile>\r
+      </PrecompiledHeaderOutputFile>\r
       <CompileAs>CompileAsC</CompileAs>\r
     </ClCompile>\r
     <ResourceCompile>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>libgc.lib;libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
-      <ModuleDefinitionFile>monosgen64.def</ModuleDefinitionFile>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
     </Link>\r
+    <PostBuildEvent>\r
+      <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+    </PostBuildEvent>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <CustomBuildStep Include="..\mono\mini\mini-x86.h">\r
   <ItemGroup>\r
     <ProjectReference Include="eglib.vcxproj">\r
       <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
-    </ProjectReference>\r
-    <ProjectReference Include="genmdesc.vcxproj">\r
-      <Project>{b7098dfa-31e6-4006-8a15-1c9a4e925149}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
     <ProjectReference Include="libgc.vcxproj">\r
       <Project>{eb56000b-c80b-4e8b-908d-d84d31b517d3}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
+    <ProjectReference Include="libmonoruntime.vcxproj">\r
+      <Project>{c36612bd-22d3-4b95-85e2-7fdc4fc5d739}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
+    <ProjectReference Include="libmonoutils.vcxproj">\r
+      <Project>{8fc2b0c8-51ad-49df-851f-5d01a77a75e4}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 646ede9538114136b145c3ee51e4f7716c01c9d6..942da86574d2625ba0b3818f70d6f6caa0cdf6de 100644 (file)
   </ImportGroup>\r
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <TargetName>$(ProjectName)sgen</TargetName>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <TargetName>$(ProjectName)sgen</TargetName>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <TargetName>$(ProjectName)sgen</TargetName>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <TargetName>$(ProjectName)sgen</TargetName>\r
   </PropertyGroup>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>WIN32;$(BOEHM_DEFINES);_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <AdditionalIncludeDirectories>$(top_srcdir);$(top_srcdir)/mono;$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE)</AdditionalIncludeDirectories>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
     </ClCompile>\r
     <Link>\r
       <SubSystem>Windows</SubSystem>\r
index 52e3dc4bc47fa8e341b87e8c279c8dfa56b647af..599febb589a161be9f828dfbfb527cce16fae33b 100644 (file)
   </ImportGroup>\r
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
-    <OutDir>$(Platform)\lib\</OutDir>\r
+    <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
     <IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
index 49eba7f2e5abc997d7cd0d422a214c77e0080a9f..64aaae18a4a7460a573e0c5dcb51fab88bf6251d 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX86</TargetMachine>\r
     </Link>\r
   </ItemDefinitionGroup>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
     </Link>\r
   </ItemDefinitionGroup>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX86</TargetMachine>\r
     </Link>\r
   </ItemDefinitionGroup>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <ProjectReference Include="eglib.vcxproj">\r
       <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 109ef31eb84c1e9be22bf4c40aba56c5a6fa87ac..97aa760a07e65fd67418ee0d363a6a711c28c060 100644 (file)
@@ -317,8 +317,6 @@ mono_g_hash_table_foreach_remove
 mono_g_hash_table_insert
 mono_g_hash_table_lookup
 mono_g_hash_table_lookup_extended
-mono_g_hash_table_new
-mono_g_hash_table_new_full
 mono_g_hash_table_new_type
 mono_g_hash_table_print_stats
 mono_g_hash_table_remove
@@ -826,11 +824,9 @@ mono_thread_detach_if_exiting
 mono_thread_exit
 mono_thread_get_main
 mono_thread_get_undeniable_exception
-mono_thread_info_clear_interruption
 mono_thread_info_exit
 mono_thread_info_finish_interrupt
 mono_thread_info_get_stack_bounds
-mono_thread_info_interrupt
 mono_thread_info_open_handle
 mono_thread_info_prepare_interrupt
 mono_thread_info_self_interrupt
@@ -844,10 +840,6 @@ mono_thread_set_main
 mono_thread_set_manage_callback
 mono_thread_stop
 mono_threads_attach_tools_thread
-mono_threads_core_clear_interruption
-mono_threads_core_finish_interrupt
-mono_threads_core_prepare_interrupt
-mono_threads_core_self_interrupt
 mono_threads_create_thread
 mono_threads_get_default_stacksize
 mono_threads_request_thread_dump
index 3ecf25bff1e7ea2cac166a736f947f6a5ce88391..84edfbbe9333ad20aba79b038b5ad20c425c1397 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(ProjectName)-sgen</TargetName>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(ProjectName)-sgen</TargetName>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(ProjectName)-sgen</TargetName>\r
     </ClCompile>\r
     <ProjectReference />\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
     </ClCompile>\r
     <ProjectReference />\r
     <Link>\r
-      <AdditionalDependencies>monosgen-2.0.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>monosgen-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
   <ItemGroup>\r
     <ProjectReference Include="eglib.vcxproj">\r
       <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index b4b2c4e5d80ff5c1a97820c2774a9a6a27eabadc..8f6320705186b24a25c3b93159d8454b11718175 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
@@ -82,7 +82,7 @@
       <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;__WIN32__;HAVE_CONFIG_H;__i386__;TARGET_X86;HOST_WIN32;TARGET_WIN32;GC_NOT_DLL;GC_GCJ_SUPPORT;GC_WIN32_THREADS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
index b9cae332c8e15b2f6857590b2f797d5dc4381b44..9a739c622b362a421674251b9cdd62456b6e8b1a 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
       <DisableSpecificWarnings>4996;4018;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>\r
     </ClCompile>\r
     <ProjectReference>\r
-      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;mono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>\r
+      </AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <Optimization>MinSpace</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
     </ClCompile>\r
     <ProjectReference>\r
-      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
       <TargetMachine>MachineX86</TargetMachine>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <DisableSpecificWarnings>4996;4018;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>\r
     </ClCompile>\r
     <ProjectReference>\r
-      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>\r
+      </AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>MinSpace</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
     </ClCompile>\r
     <ProjectReference>\r
-      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX64</TargetMachine>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\mono\dis\util.h" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ProjectReference Include="eglib.vcxproj">\r
+      <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index f77df6ffae81890739e5eadd50d0029204d392c4..962d5bacf515679a4d14793cf9b3ec324692db47 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
@@ -95,7 +95,7 @@
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;mono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
     <ClCompile>\r
       <Optimization>MinSpace</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>ws2_32.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>MinSpace</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\mono\monograph\monograph.c" />\r
     <ClCompile Include="..\mono\metadata\opcodes.c" />\r
+    <ClCompile Include="..\tools\monograph\monograph.c" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ProjectReference Include="eglib.vcxproj">\r
+      <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 8fd2d718c9090383136ee828abc03868c31fd7b1..df216b7622ccae357b321e8ac672676996079786 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MonoPosixHelper</TargetName>\r
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MonoPosixHelper</TargetName>\r
@@ -94,7 +94,7 @@
       <CompileAs>CompileAsC</CompileAs>\r
     </ClCompile>\r
     <Link>\r
-      <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\r
       <ModuleDefinitionFile>monoposixhelper.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX86</TargetMachine>\r
     </Link>\r
   </ItemDefinitionGroup>\r
       <ModuleDefinitionFile>monoposixhelper.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
       <CompileAs>CompileAsC</CompileAs>\r
     </ClCompile>\r
     <Link>\r
-      <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\r
       <ModuleDefinitionFile>monoposixhelper.def</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX86</TargetMachine>\r
     </Link>\r
   </ItemDefinitionGroup>\r
       <SubSystem>Windows</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
-      <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+      <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <None Include="monoposixhelper.def" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ProjectReference Include="eglib.vcxproj">\r
+      <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+    </ProjectReference>\r
     <ProjectReference Include="genmdesc.vcxproj">\r
       <Project>{b7098dfa-31e6-4006-8a15-1c9a4e925149}</Project>\r
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
index eb44f062a3faea6fb3254903257c48c375eedffc..215e64142f1f1bcd82fc1549991954e4b191a10b 100644 (file)
@@ -317,8 +317,6 @@ mono_g_hash_table_foreach_remove
 mono_g_hash_table_insert
 mono_g_hash_table_lookup
 mono_g_hash_table_lookup_extended
-mono_g_hash_table_new
-mono_g_hash_table_new_full
 mono_g_hash_table_new_type
 mono_g_hash_table_print_stats
 mono_g_hash_table_remove
@@ -474,8 +472,6 @@ mono_install_assembly_refonly_preload_hook
 mono_install_assembly_refonly_search_hook
 mono_install_assembly_search_hook
 mono_install_runtime_cleanup
-mono_install_threadpool_item_hooks
-mono_install_threadpool_thread_hooks
 mono_install_unhandled_exception_hook
 mono_invoke_unhandled_exception_hook
 mono_is_debugger_attached
@@ -831,11 +827,8 @@ mono_thread_detach_if_exiting
 mono_thread_exit
 mono_thread_get_main
 mono_thread_get_undeniable_exception
-mono_thread_info_clear_interruption
 mono_thread_info_exit
-mono_thread_info_finish_interrupt
 mono_thread_info_get_stack_bounds
-mono_thread_info_interrupt
 mono_thread_info_open_handle
 mono_thread_info_prepare_interrupt
 mono_thread_info_self_interrupt
@@ -849,10 +842,6 @@ mono_thread_set_main
 mono_thread_set_manage_callback
 mono_thread_stop
 mono_threads_attach_tools_thread
-mono_threads_core_clear_interruption
-mono_threads_core_finish_interrupt
-mono_threads_core_prepare_interrupt
-mono_threads_core_self_interrupt
 mono_threads_create_thread
 mono_threads_get_default_stacksize
 mono_threads_request_thread_dump
@@ -906,4 +895,3 @@ mono_win32_compat_CopyMemory
 mono_win32_compat_FillMemory
 mono_win32_compat_MoveMemory
 mono_win32_compat_ZeroMemory
-mono_xdebug_flush
diff --git a/msvc/monosgen64.def b/msvc/monosgen64.def
deleted file mode 100644 (file)
index f77f019..0000000
+++ /dev/null
@@ -1,862 +0,0 @@
-; file generated by create-windef.pl
-LIBRARY monosgen-2.0.dll
-EXPORTS
-MonoFixupCorEE
-mono_add_internal_call
-mono_aot_register_globals
-mono_aot_register_module
-mono_array_addr_with_size
-mono_array_class_get
-mono_array_clone
-mono_array_element_size
-mono_array_length
-mono_array_new
-mono_array_new_full
-mono_array_new_specific
-mono_assemblies_cleanup
-mono_assemblies_init
-mono_assembly_close
-mono_assembly_fill_assembly_name
-mono_assembly_foreach
-mono_assembly_get_assemblyref
-mono_assembly_get_image
-mono_assembly_get_main
-mono_assembly_get_object
-mono_assembly_getrootdir
-mono_assembly_invoke_load_hook
-mono_assembly_invoke_search_hook
-mono_assembly_load
-mono_assembly_load_from
-mono_assembly_load_from_full
-mono_assembly_load_full
-mono_assembly_load_module
-mono_assembly_load_reference
-mono_assembly_load_references
-mono_assembly_load_with_partial_name
-mono_assembly_loaded
-mono_assembly_loaded_full
-mono_assembly_name_free
-mono_assembly_name_get_culture
-mono_assembly_name_get_name
-mono_assembly_name_get_pubkeytoken
-mono_assembly_name_get_version
-mono_assembly_name_new
-mono_assembly_names_equal
-mono_assembly_open
-mono_assembly_open_full
-mono_assembly_set_main
-mono_assembly_setrootdir
-mono_binary_search
-mono_bitset_alloc_size
-mono_bitset_clear
-mono_bitset_clear_all
-mono_bitset_clone
-mono_bitset_copyto
-mono_bitset_count
-mono_bitset_equal
-mono_bitset_find_first
-mono_bitset_find_first_unset
-mono_bitset_find_last
-mono_bitset_find_start
-mono_bitset_foreach
-mono_bitset_free
-mono_bitset_intersection
-mono_bitset_intersection_2
-mono_bitset_invert
-mono_bitset_mem_new
-mono_bitset_new
-mono_bitset_set
-mono_bitset_set_all
-mono_bitset_size
-mono_bitset_sub
-mono_bitset_test
-mono_bitset_test_bulk
-mono_bitset_union
-mono_bounded_array_class_get
-mono_breakpoint_clean_code
-mono_check_corlib_version
-mono_class_array_element_size
-mono_class_data_size
-mono_class_describe_statics
-mono_class_enum_basetype
-mono_class_from_generic_parameter
-mono_class_from_mono_type
-mono_class_from_name
-mono_class_from_name_case
-mono_class_from_typeref
-mono_class_get
-mono_class_get_byref_type
-mono_class_get_com_object_class
-mono_class_get_element_class
-mono_class_get_event_token
-mono_class_get_events
-mono_class_get_field
-mono_class_get_field_from_name
-mono_class_get_field_token
-mono_class_get_fields
-mono_class_get_flags
-mono_class_get_full
-mono_class_get_idispatch_class
-mono_class_get_image
-mono_class_get_interfaces
-mono_class_get_interop_proxy_class
-mono_class_get_iunknown_class
-mono_class_get_method_from_name
-mono_class_get_method_from_name_flags
-mono_class_get_methods
-mono_class_get_name
-mono_class_get_namespace
-mono_class_get_nested_types
-mono_class_get_nesting_type
-mono_class_get_parent
-mono_class_get_properties
-mono_class_get_property_from_name
-mono_class_get_property_token
-mono_class_get_rank
-mono_class_get_type
-mono_class_get_type_token
-mono_class_get_variant_class
-mono_class_implements_interface
-mono_class_inflate_generic_method
-mono_class_inflate_generic_type
-mono_class_init
-mono_class_instance_size
-mono_class_interface_offset
-mono_class_is_assignable_from
-mono_class_is_delegate
-mono_class_is_enum
-mono_class_is_subclass_of
-mono_class_is_valid_enum
-mono_class_is_valuetype
-mono_class_min_align
-mono_class_name_from_token
-mono_class_num_events
-mono_class_num_fields
-mono_class_num_methods
-mono_class_num_properties
-mono_class_value_size
-mono_class_vtable
-mono_cli_rva_image_map
-mono_code_manager_cleanup
-mono_code_manager_commit
-mono_code_manager_destroy
-mono_code_manager_foreach
-mono_code_manager_init
-mono_code_manager_invalidate
-mono_code_manager_new
-mono_code_manager_new_dynamic
-mono_code_manager_reserve
-mono_code_manager_reserve_align
-mono_code_manager_set_read_only
-mono_code_manager_size
-mono_compile_method
-mono_config_cleanup
-mono_config_for_assembly
-mono_config_is_server_mode
-mono_config_parse
-mono_config_parse_memory
-mono_config_set_server_mode
-mono_config_string_for_assembly_file
-mono_context_get
-mono_context_get_desc
-mono_context_init
-mono_context_set
-mono_counters_cleanup
-mono_counters_dump
-mono_counters_enable
-mono_counters_register
-mono_custom_attrs_construct
-mono_custom_attrs_free
-mono_custom_attrs_from_assembly
-mono_custom_attrs_from_class
-mono_custom_attrs_from_event
-mono_custom_attrs_from_field
-mono_custom_attrs_from_index
-mono_custom_attrs_from_method
-mono_custom_attrs_from_param
-mono_custom_attrs_from_property
-mono_custom_attrs_get_attr
-mono_custom_attrs_has_attr
-mono_debug_add_delegate_trampoline
-mono_debug_add_method
-mono_debug_cleanup
-mono_debug_close_image
-mono_debug_close_mono_symbol_file
-mono_debug_domain_create
-mono_debug_domain_unload
-mono_debug_enabled
-mono_debug_find_method
-mono_debug_free_method_jit_info
-mono_debug_free_source_location
-mono_debug_il_offset_from_address
-mono_debug_init
-mono_debug_list_add
-mono_debug_list_remove
-mono_debug_lookup_locals
-mono_debug_lookup_method
-mono_debug_lookup_method_addresses
-mono_debug_lookup_source_location
-mono_debug_open_image_from_memory
-mono_debug_open_mono_symbols
-mono_debug_print_stack_frame
-mono_debug_print_vars
-mono_debug_remove_method
-mono_debug_symfile_free_locals
-mono_debug_symfile_free_location
-mono_debug_symfile_get_line_numbers
-mono_debug_symfile_get_line_numbers_full
-mono_debug_symfile_is_loaded
-mono_debug_symfile_lookup_locals
-mono_debug_symfile_lookup_location
-mono_debug_symfile_lookup_method
-mono_debugger_insert_breakpoint
-mono_debugger_method_has_breakpoint
-mono_debugger_run_finally
-mono_declsec_flags_from_assembly
-mono_declsec_flags_from_class
-mono_declsec_flags_from_method
-mono_declsec_get_assembly_action
-mono_declsec_get_class_action
-mono_declsec_get_demands
-mono_declsec_get_inheritdemands_class
-mono_declsec_get_inheritdemands_method
-mono_declsec_get_linkdemands
-mono_declsec_get_method_action
-mono_digest_get_public_token
-mono_disasm_code
-mono_disasm_code_one
-mono_dl_fallback_register
-mono_dl_fallback_unregister
-mono_dllmap_insert
-mono_domain_add_class_static_data
-mono_domain_assembly_open
-mono_domain_create
-mono_domain_create_appdomain
-mono_domain_finalize
-mono_domain_foreach
-mono_domain_free
-mono_domain_from_appdomain
-mono_domain_get
-mono_domain_get_by_id
-mono_domain_get_id
-mono_domain_has_type_resolve
-mono_domain_is_unloading
-mono_domain_owns_vtable_slot
-mono_domain_set
-mono_domain_set_config
-mono_domain_set_internal
-mono_domain_try_type_resolve
-mono_domain_try_unload
-mono_domain_unload
-mono_dwarf_escape_path
-mono_emit_native_call
-mono_environment_exitcode_get
-mono_environment_exitcode_set
-mono_error_cleanup
-mono_error_get_error_code
-mono_error_get_message
-mono_error_init
-mono_error_init_flags
-mono_error_ok
-mono_escape_uri_string
-mono_event_get_add_method
-mono_event_get_flags
-mono_event_get_name
-mono_event_get_object
-mono_event_get_parent
-mono_event_get_raise_method
-mono_event_get_remove_method
-mono_exception_from_name
-mono_exception_from_name_domain
-mono_exception_from_name_msg
-mono_exception_from_name_two_strings
-mono_exception_from_token
-mono_exception_from_token_two_strings
-mono_exception_walk_trace
-mono_field_from_token
-mono_field_full_name
-mono_field_get_data
-mono_field_get_flags
-mono_field_get_name
-mono_field_get_object
-mono_field_get_offset
-mono_field_get_parent
-mono_field_get_type
-mono_field_get_value
-mono_field_get_value_object
-mono_field_set_value
-mono_field_static_get_value
-mono_field_static_set_value
-mono_file_map
-mono_file_map_close
-mono_file_map_fd
-mono_file_map_open
-mono_file_map_size
-mono_file_unmap
-mono_free
-mono_free_bstr
-mono_free_method
-mono_free_verify_list
-mono_g_hash_table_destroy
-mono_g_hash_table_find
-mono_g_hash_table_foreach
-mono_g_hash_table_foreach_remove
-mono_g_hash_table_insert
-mono_g_hash_table_lookup
-mono_g_hash_table_lookup_extended
-mono_g_hash_table_new
-mono_g_hash_table_new_full
-mono_g_hash_table_new_type
-mono_g_hash_table_print_stats
-mono_g_hash_table_remove
-mono_g_hash_table_replace
-mono_g_hash_table_size
-mono_gc_collect
-mono_gc_collection_count
-mono_gc_get_generation
-mono_gc_get_heap_size
-mono_gc_get_used_size
-mono_gc_invoke_finalizers
-mono_gc_max_generation
-mono_gc_reference_queue_add
-mono_gc_reference_queue_free
-mono_gc_reference_queue_new
-mono_gc_toggleref_add
-mono_gc_toggleref_register_callback
-mono_gc_walk_heap
-mono_gc_wbarrier_arrayref_copy
-mono_gc_wbarrier_generic_nostore
-mono_gc_wbarrier_generic_store
-mono_gc_wbarrier_generic_store_atomic
-mono_gc_wbarrier_object_copy
-mono_gc_wbarrier_set_arrayref
-mono_gc_wbarrier_set_field
-mono_gc_wbarrier_value_copy
-mono_gchandle_free
-mono_gchandle_get_target
-mono_gchandle_new
-mono_gchandle_new_weakref
-mono_get_array_class
-mono_get_boolean_class
-mono_get_byte_class
-mono_get_char_class
-mono_get_config_dir
-mono_get_corlib
-mono_get_dbnull_object
-mono_get_delegate_begin_invoke
-mono_get_delegate_end_invoke
-mono_get_delegate_invoke
-mono_get_double_class
-mono_get_enum_class
-mono_get_exception_appdomain_unloaded
-mono_get_exception_argument
-mono_get_exception_argument_null
-mono_get_exception_argument_out_of_range
-mono_get_exception_arithmetic
-mono_get_exception_array_type_mismatch
-mono_get_exception_bad_image_format
-mono_get_exception_bad_image_format2
-mono_get_exception_cannot_unload_appdomain
-mono_get_exception_class
-mono_get_exception_divide_by_zero
-mono_get_exception_execution_engine
-mono_get_exception_field_access
-mono_get_exception_file_not_found
-mono_get_exception_file_not_found2
-mono_get_exception_index_out_of_range
-mono_get_exception_invalid_cast
-mono_get_exception_invalid_operation
-mono_get_exception_io
-mono_get_exception_method_access
-mono_get_exception_missing_field
-mono_get_exception_missing_method
-mono_get_exception_not_implemented
-mono_get_exception_not_supported
-mono_get_exception_null_reference
-mono_get_exception_out_of_memory
-mono_get_exception_overflow
-mono_get_exception_reflection_type_load
-mono_get_exception_runtime_wrapped
-mono_get_exception_security
-mono_get_exception_serialization
-mono_get_exception_stack_overflow
-mono_get_exception_synchronization_lock
-mono_get_exception_thread_abort
-mono_get_exception_thread_interrupted
-mono_get_exception_thread_state
-mono_get_exception_type_initialization
-mono_get_exception_type_load
-mono_get_inflated_method
-mono_get_int16_class
-mono_get_int32_class
-mono_get_int64_class
-mono_get_intptr_class
-mono_get_machine_config
-mono_get_method
-mono_get_method_constrained
-mono_get_method_full
-mono_get_object_class
-mono_get_root_domain
-mono_get_runtime_build_info
-mono_get_sbyte_class
-mono_get_single_class
-mono_get_string_class
-mono_get_thread_class
-mono_get_trampoline_func
-mono_get_uint16_class
-mono_get_uint32_class
-mono_get_uint64_class
-mono_get_uintptr_class
-mono_get_void_class
-mono_guid_to_string
-mono_image_add_to_name_cache
-mono_image_addref
-mono_image_close
-mono_image_ensure_section
-mono_image_ensure_section_idx
-mono_image_fixup_vtable
-mono_image_get_assembly
-mono_image_get_entry_point
-mono_image_get_filename
-mono_image_get_guid
-mono_image_get_name
-mono_image_get_public_key
-mono_image_get_resource
-mono_image_get_strong_name
-mono_image_get_table_info
-mono_image_get_table_rows
-mono_image_has_authenticode_entry
-mono_image_init
-mono_image_init_name_cache
-mono_image_is_dynamic
-mono_image_load_file_for_image
-mono_image_load_module
-mono_image_loaded
-mono_image_loaded_by_guid
-mono_image_loaded_by_guid_full
-mono_image_loaded_full
-mono_image_lookup_resource
-mono_image_open
-mono_image_open_from_data
-mono_image_open_from_data_full
-mono_image_open_from_data_with_name
-mono_image_open_full
-mono_image_rva_map
-mono_image_strerror
-mono_image_strong_name_position
-mono_images_cleanup
-mono_images_init
-mono_init
-mono_init_from_assembly
-mono_init_version
-mono_inst_name
-mono_install_assembly_load_hook
-mono_install_assembly_postload_refonly_search_hook
-mono_install_assembly_postload_search_hook
-mono_install_assembly_preload_hook
-mono_install_assembly_refonly_preload_hook
-mono_install_assembly_refonly_search_hook
-mono_install_assembly_search_hook
-mono_install_runtime_cleanup
-mono_install_threadpool_item_hooks
-mono_install_threadpool_thread_hooks
-mono_install_unhandled_exception_hook
-mono_invoke_unhandled_exception_hook
-mono_is_debugger_attached
-mono_jit_cleanup
-mono_jit_exec
-mono_jit_info_get_code_size
-mono_jit_info_get_code_start
-mono_jit_info_get_method
-mono_jit_info_table_find
-mono_jit_init
-mono_jit_init_version
-mono_jit_parse_options
-mono_jit_set_aot_only
-mono_jit_set_domain
-mono_jit_set_trace_options
-mono_jit_thread_attach
-mono_ldstr
-mono_ldtoken
-mono_lls_init
-mono_load_remote_field
-mono_load_remote_field_new
-mono_local_deadce
-mono_locks_dump
-mono_lookup_icall_symbol
-mono_lookup_internal_call
-mono_lookup_pinvoke_call
-mono_main
-mono_marshal_string_to_utf16
-mono_md5_final
-mono_md5_get_digest
-mono_md5_get_digest_from_file
-mono_md5_init
-mono_md5_update
-mono_mempool_alloc
-mono_mempool_alloc0
-mono_mempool_contains_addr
-mono_mempool_destroy
-mono_mempool_empty
-mono_mempool_get_allocated
-mono_mempool_invalidate
-mono_mempool_new
-mono_mempool_new_size
-mono_mempool_stats
-mono_mempool_strdup
-mono_metadata_blob_heap
-mono_metadata_cleanup
-mono_metadata_compute_size
-mono_metadata_custom_attrs_from_index
-mono_metadata_declsec_from_index
-mono_metadata_decode_blob_size
-mono_metadata_decode_row
-mono_metadata_decode_row_col
-mono_metadata_decode_signed_value
-mono_metadata_decode_table_row
-mono_metadata_decode_table_row_col
-mono_metadata_decode_value
-mono_metadata_encode_value
-mono_metadata_events_from_typedef
-mono_metadata_field_info
-mono_metadata_field_info_with_mempool
-mono_metadata_free_array
-mono_metadata_free_inflated_signature
-mono_metadata_free_marshal_spec
-mono_metadata_free_method_signature
-mono_metadata_free_mh
-mono_metadata_free_type
-mono_metadata_generic_class_is_valuetype
-mono_metadata_get_constant_index
-mono_metadata_get_generic_param_row
-mono_metadata_get_inflated_signature
-mono_metadata_get_marshal_info
-mono_metadata_guid_heap
-mono_metadata_implmap_from_method
-mono_metadata_init
-mono_metadata_interfaces_from_typedef
-mono_metadata_load_generic_param_constraints
-mono_metadata_load_generic_params
-mono_metadata_locate
-mono_metadata_locate_token
-mono_metadata_methods_from_event
-mono_metadata_methods_from_property
-mono_metadata_nested_in_typedef
-mono_metadata_nesting_typedef
-mono_metadata_packing_from_typedef
-mono_metadata_parse_array
-mono_metadata_parse_custom_mod
-mono_metadata_parse_field_type
-mono_metadata_parse_marshal_spec
-mono_metadata_parse_method_signature
-mono_metadata_parse_method_signature_full
-mono_metadata_parse_mh
-mono_metadata_parse_mh_full
-mono_metadata_parse_param
-mono_metadata_parse_signature
-mono_metadata_parse_type
-mono_metadata_parse_type_full
-mono_metadata_parse_typedef_or_ref
-mono_metadata_properties_from_typedef
-mono_metadata_signature_alloc
-mono_metadata_signature_dup
-mono_metadata_signature_equal
-mono_metadata_string_heap
-mono_metadata_token_from_dor
-mono_metadata_translate_token_index
-mono_metadata_type_equal
-mono_metadata_type_hash
-mono_metadata_typedef_from_field
-mono_metadata_typedef_from_method
-mono_metadata_user_string
-mono_method_body_get_object
-mono_method_can_access_field
-mono_method_can_access_method
-mono_method_desc_free
-mono_method_desc_from_method
-mono_method_desc_full_match
-mono_method_desc_match
-mono_method_desc_new
-mono_method_desc_search_in_class
-mono_method_desc_search_in_image
-mono_method_full_name
-mono_method_get_class
-mono_method_get_flags
-mono_method_get_generic_container
-mono_method_get_header
-mono_method_get_index
-mono_method_get_last_managed
-mono_method_get_marshal_info
-mono_method_get_name
-mono_method_get_object
-mono_method_get_param_names
-mono_method_get_param_token
-mono_method_get_signature
-mono_method_get_signature_full
-mono_method_get_token
-mono_method_get_unmanaged_thunk
-mono_method_has_marshal_info
-mono_method_header_get_clauses
-mono_method_header_get_code
-mono_method_header_get_locals
-mono_method_header_get_num_clauses
-mono_method_signature
-mono_method_verify
-mono_mlist_alloc
-mono_mlist_append
-mono_mlist_get_data
-mono_mlist_last
-mono_mlist_length
-mono_mlist_next
-mono_mlist_prepend
-mono_mlist_remove_item
-mono_mlist_set_data
-mono_mlist_set_next
-mono_module_file_get_object
-mono_module_get_object
-mono_monitor_enter
-mono_monitor_exit
-mono_monitor_try_enter
-mono_mprotect
-mono_mutex_init_suspend_safe
-mono_object_castclass_mbyref
-mono_object_castclass_with_cache
-mono_object_clone
-mono_object_describe
-mono_object_describe_fields
-mono_object_get_class
-mono_object_get_domain
-mono_object_get_size
-mono_object_get_virtual_method
-mono_object_hash
-mono_object_isinst
-mono_object_isinst_mbyref
-mono_object_isinst_with_cache
-mono_object_new
-mono_object_new_alloc_specific
-mono_object_new_fast
-mono_object_new_from_token
-mono_object_new_specific
-mono_object_to_string
-mono_object_unbox
-mono_op_to_op_imm_noemul
-mono_opcode_name
-mono_opcode_value
-mono_pagesize
-mono_param_get_objects
-mono_parse_default_optimizations
-mono_path_canonicalize
-mono_path_resolve_symlinks
-mono_pe_file_open
-mono_perfcounters_init
-mono_pmip
-mono_poll
-mono_print_method_from_ip
-mono_print_thread_dump
-mono_print_thread_dump_from_ctx
-mono_print_unhandled_exception
-mono_profiler_coverage_get
-mono_profiler_get_events
-mono_profiler_install
-mono_profiler_install_allocation
-mono_profiler_install_appdomain
-mono_profiler_install_assembly
-mono_profiler_install_class
-mono_profiler_install_code_buffer_new
-mono_profiler_install_code_chunk_destroy
-mono_profiler_install_code_chunk_new
-mono_profiler_install_coverage_filter
-mono_profiler_install_enter_leave
-mono_profiler_install_exception
-mono_profiler_install_gc
-mono_profiler_install_gc_moves
-mono_profiler_install_gc_roots
-mono_profiler_install_iomap
-mono_profiler_install_jit_compile
-mono_profiler_install_jit_end
-mono_profiler_install_method_free
-mono_profiler_install_method_invoke
-mono_profiler_install_module
-mono_profiler_install_monitor
-mono_profiler_install_runtime_initialized
-mono_profiler_install_statistical
-mono_profiler_install_statistical_call_chain
-mono_profiler_install_thread
-mono_profiler_install_thread_name
-mono_profiler_install_transition
-mono_profiler_load
-mono_profiler_set_events
-mono_property_get_flags
-mono_property_get_get_method
-mono_property_get_name
-mono_property_get_object
-mono_property_get_parent
-mono_property_get_set_method
-mono_property_get_value
-mono_property_hash_destroy
-mono_property_hash_insert
-mono_property_hash_lookup
-mono_property_hash_new
-mono_property_hash_remove_object
-mono_property_set_value
-mono_ptr_class_get
-mono_raise_exception
-mono_realloc_native_code
-mono_reflection_free_type_info
-mono_reflection_get_custom_attrs
-mono_reflection_get_custom_attrs_blob
-mono_reflection_get_custom_attrs_by_type
-mono_reflection_get_custom_attrs_data
-mono_reflection_get_custom_attrs_info
-mono_reflection_get_token
-mono_reflection_get_type
-mono_reflection_parse_type
-mono_reflection_type_from_name
-mono_reflection_type_get_type
-mono_register_bundled_assemblies
-mono_register_config_for_assembly
-mono_register_machine_config
-mono_register_symfile_for_assembly
-mono_replace_ins
-mono_runtime_class_init
-mono_runtime_cleanup
-mono_runtime_delegate_invoke
-mono_runtime_exec_main
-mono_runtime_exec_managed_code
-mono_runtime_get_main_args
-mono_runtime_init
-mono_runtime_invoke
-mono_runtime_invoke_array
-mono_runtime_is_shutting_down
-mono_runtime_object_init
-mono_runtime_quit
-mono_runtime_resource_check_limit
-mono_runtime_resource_limit
-mono_runtime_resource_set_callback
-mono_runtime_run_main
-mono_runtime_set_shutting_down
-mono_security_core_clr_get_options
-mono_security_core_clr_require_elevated_permissions
-mono_security_core_clr_set_options
-mono_security_enable_core_clr
-mono_security_set_core_clr_platform_callback
-mono_sem_post
-mono_sem_timedwait
-mono_sem_wait
-mono_set_assemblies_path
-mono_set_break_policy
-mono_set_config_dir
-mono_set_defaults
-mono_set_dirs
-mono_set_is_debugger_attached
-mono_set_rootdir
-mono_set_signal_chaining
-mono_sha1_final
-mono_sha1_get_digest
-mono_sha1_get_digest_from_file
-mono_sha1_init
-mono_sha1_update
-mono_shared_area
-mono_shared_area_for_pid
-mono_shared_area_instances
-mono_shared_area_remove
-mono_shared_area_unload
-mono_signature_explicit_this
-mono_signature_get_call_conv
-mono_signature_get_desc
-mono_signature_get_param_count
-mono_signature_get_params
-mono_signature_get_return_type
-mono_signature_hash
-mono_signature_is_instance
-mono_signature_param_is_out
-mono_signature_vararg_start
-mono_signbit_double
-mono_signbit_float
-mono_stack_walk
-mono_stack_walk_no_il
-mono_store_remote_field
-mono_store_remote_field_new
-mono_string_chars
-mono_string_equal
-mono_string_from_bstr
-mono_string_from_utf16
-mono_string_hash
-mono_string_intern
-mono_string_is_interned
-mono_string_length
-mono_string_new
-mono_string_new_len
-mono_string_new_size
-mono_string_new_utf16
-mono_string_new_wrapper
-mono_string_to_utf16
-mono_string_to_utf8
-mono_string_to_utf8_checked
-mono_stringify_assembly_name
-mono_table_info_get_rows
-mono_thread_attach
-mono_thread_cleanup
-mono_thread_create
-mono_thread_current
-mono_thread_detach
-mono_thread_exit
-mono_thread_get_main
-mono_thread_get_undeniable_exception
-mono_thread_init
-mono_thread_is_foreign
-mono_thread_manage
-mono_thread_new_init
-mono_thread_set_main
-mono_thread_set_manage_callback
-mono_thread_stop
-mono_threads_get_default_stacksize
-mono_threads_request_thread_dump
-mono_threads_set_default_stacksize
-mono_tls_key_get_offset
-mono_tls_key_set_offset
-mono_trace_set_level_string
-mono_trace_set_mask_string
-mono_type_create_from_typespec
-mono_type_full_name
-mono_type_generic_inst_is_valuetype
-mono_type_get_array_type
-mono_type_get_class
-mono_type_get_desc
-mono_type_get_modifiers
-mono_type_get_name
-mono_type_get_object
-mono_type_get_ptr_type
-mono_type_get_signature
-mono_type_get_type
-mono_type_get_underlying_type
-mono_type_is_byref
-mono_type_is_pointer
-mono_type_is_reference
-mono_type_is_struct
-mono_type_is_valid_enum_basetype
-mono_type_is_void
-mono_type_size
-mono_type_stack_size
-mono_type_to_unmanaged
-mono_unhandled_exception
-mono_unicode_from_external
-mono_unicode_to_external
-mono_upgrade_remote_class_wrapper
-mono_utf8_from_external
-mono_utf8_validate_and_len
-mono_utf8_validate_and_len_with_bounds
-mono_valloc
-mono_valloc_aligned
-mono_value_box
-mono_value_copy
-mono_value_copy_array
-mono_value_describe_fields
-mono_verify_corlib
-mono_vfree
-mono_vtable_get_static_field_data
-mono_win32_compat_CopyMemory
-mono_win32_compat_FillMemory
-mono_win32_compat_MoveMemory
-mono_win32_compat_ZeroMemory
-mono_xdebug_flush
index 5e57c01b5dd91ad006d1752bfd865ecd40daa186..275e4c17c95efe7c35b181ead4fa308851e7bf6e 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\libgc\include;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;GC_NOT_DLL;GC_GCJ_SUPPORT;GC_WIN32_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
@@ -98,7 +98,7 @@
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libgc.lib;mono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\;..\libgc\include;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\mono\utils\strtod.c" />\r
     <ClCompile Include="..\mono\metadata\appdomain.c" />\r
     <ClCompile Include="..\mono\metadata\assembly.c" />\r
     <ClCompile Include="..\mono\metadata\boehm-gc.c" />\r
     <ClCompile Include="..\mono\metadata\class.c" />\r
     <ClCompile Include="..\mono\metadata\console-win32.c" />\r
-    <ClCompile Include="..\mono\metadata\decimal.c" />\r
     <ClCompile Include="..\mono\metadata\domain.c" />\r
     <ClCompile Include="..\mono\metadata\environment.c" />\r
     <ClCompile Include="..\mono\metadata\file-io.c" />\r
     <ClCompile Include="..\mono\metadata\process.c" />\r
     <ClCompile Include="..\mono\metadata\profiler.c" />\r
     <ClCompile Include="..\mono\metadata\rand.c" />\r
-    <ClCompile Include="..\mono\metadata\rawbuffer.c" />\r
     <ClCompile Include="..\mono\metadata\reflection.c" />\r
     <ClCompile Include="..\mono\metadata\security-manager.c" />\r
-    <ClCompile Include="..\mono\metadata\security.c" />\r
     <ClCompile Include="..\mono\metadata\socket-io.c" />\r
     <ClCompile Include="..\mono\metadata\string-icalls.c" />\r
     <ClCompile Include="..\mono\metadata\sysmath.c" />\r
-    <ClCompile Include="..\mono\metadata\threadpool.c" />\r
     <ClCompile Include="..\mono\metadata\threads.c" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ProjectReference Include="eglib.vcxproj">\r
+      <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
+    <ProjectReference Include="libgc.vcxproj">\r
+      <Project>{eb56000b-c80b-4e8b-908d-d84d31b517d3}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
+    <ProjectReference Include="libmonoruntime.vcxproj">\r
+      <Project>{c36612bd-22d3-4b95-85e2-7fdc4fc5d739}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+    </ProjectReference>\r
+    <ProjectReference Include="libmonoutils.vcxproj">\r
+      <Project>{8fc2b0c8-51ad-49df-851f-5d01a77a75e4}</Project>\r
+      <Private>false</Private>\r
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index ecfc8d6953c2c425241da579a84e2ce28e4d254a..2088fa3f0acf3f4f0573e740b00ff492b00a37d3 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
@@ -97,7 +97,7 @@
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 3159e42dbb82f9e1cca8e6ccd4a1fa93f00d1eba..42a5bd68e092bd3c059328a98257b833996cd210 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\include;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
@@ -97,7 +97,7 @@
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\include;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 69a9aefb9c0520e2952dd187cb6317620c5e553e..6986e99de777b4c346960db7ce742ce6668b42a0 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
@@ -89,7 +89,7 @@
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <OptimizeReferences>false</OptimizeReferences>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <DataExecutionPrevention>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <OptimizeReferences>false</OptimizeReferences>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <TargetMachine>MachineX64</TargetMachine>\r
     </Link>\r
     <ProjectReference Include="eglib.vcxproj">\r
       <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 8ec30a352f2d7ebbb1973164d584c3c912448348..772dd3692c51cebdf903baa56d5465c814a8cecd 100644 (file)
   <PropertyGroup Label="UserMacros" />\r
   <PropertyGroup>\r
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
@@ -97,7 +97,7 @@
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </Midl>\r
     <ClCompile>\r
       <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <MinimalRebuild>true</MinimalRebuild>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       </PrecompiledHeader>\r
       <WarningLevel>Level3</WarningLevel>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
     </ClCompile>\r
     <ProjectReference>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     <ProjectReference Include="libmono.vcxproj">\r
       <Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+      <Private>false</Private>\r
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 5c1cb7cee5eb79460fcd343ab05c4ab09adfe674..f72e5934198cd5fa58cbfae02c5b25abb2f80f29 100644 (file)
@@ -37,7 +37,11 @@ build_profiles += monodroid
 endif
 
 if INSTALL_MONOTOUCH
-build_profiles += monotouch monotouch_runtime monotouch_watch
+build_profiles += monotouch monotouch_runtime
+endif
+
+if INSTALL_MONOTOUCH_WATCH
+build_profiles += monotouch_watch
 endif
 
 if INSTALL_XAMMAC
index 155690d75adad1c75ec255675b443167bc94089f..5e440ab046bf8a6058aed1214e51a7ecc400234e 100644 (file)
@@ -14,7 +14,7 @@ monolist=($(printf "%s\n" "${filelist[@]}" | egrep "\\.(exe|dll)\$"))
 
 # Only include files with /gac/ in path
 #  (Allows packages to contain private assemblies that don't conflict with other packages)
-#monolist=($(printf "%s\n" "${monolist[@]}" | egrep "/gac/"))
+monolist=($(printf "%s\n" "${monolist[@]}" | egrep "/gac/"))
 # Disabled... see ChangeLog
 
 # Set the prefix, unless it is overriden (used when building mono rpms)
index c91511cf0e24d3f70f944a3e2676c44b92c2f01a..79154fc99bbd9b232eb8c4bd1e16119b07d9bb45 100644 (file)
@@ -39,6 +39,7 @@ MPH_UNIX_SOURCE =                             \
        serial.c                                \
        sys-mman.c                              \
        sys-sendfile.c                          \
+       sys-socket.c                            \
        sys-stat.c                              \
        sys-statvfs.c                           \
        sys-time.c                              \
@@ -135,12 +136,14 @@ refresh:
        --impl-macro=_GNU_SOURCE --impl-macro=_XOPEN_SOURCE   \
        --impl-header="<sys/types.h>"                         \
        --impl-header="<sys/stat.h>"                          \
+       --autoconf-header="<netinet/in.h>"                    \
        --autoconf-header="<sys/time.h>"                      \
        --autoconf-header="<sys/poll.h>"                      \
        --autoconf-header="<sys/wait.h>"                      \
        --autoconf-header="<sys/statvfs.h>"                   \
        --autoconf-header="<sys/xattr.h>"                     \
        --autoconf-header="<sys/mman.h>"                      \
+       --autoconf-header="<sys/socket.h>"                    \
        --autoconf-header="<sys/uio.h>"                       \
        --autoconf-header="<unistd.h>"                        \
        --impl-header="<fcntl.h>"                             \
@@ -158,7 +161,7 @@ refresh:
        --rename-member=st_mtime=st_mtime_                    \
        --rename-namespace=Mono.Unix.Native=Mono.Posix        \
        --library=MonoPosixHelper                             \
-       $(mcs_topdir)/class/lib/net_4_5/Mono.Posix.dll map
+       $(mcs_topdir)/class/lib/net_4_x/Mono.Posix.dll map
 
 # Useful if mono is compiled with --enable-shared=no
 patch-libtool:
index 26ee780169183aff8538e23987818f38721356f4..384451da47c4af2149080cad2de18498e7be577b 100644 (file)
@@ -35,7 +35,7 @@ Mono_Posix_Stdlib_SetLastError (int error_number)
  * we assume that the XPG version is present.
  */
 
-#ifdef _GNU_SOURCE
+#ifdef _GNU_SOURCE && !PLATFORM_ANDROID
 #define mph_min(x,y) ((x) <= (y) ? (x) : (y))
 
 /* If you pass an invalid errno value to glibc 2.3.2's strerror_r, you get
@@ -80,7 +80,27 @@ Mono_Posix_Syscall_strerror_r (int errnum, char *buf, mph_size_t n)
        mph_return_if_size_t_overflow (n);
 
        /* first, check for valid errnum */
+#if PLATFORM_ANDROID
+       /* Android NDK defines _GNU_SOURCE but strerror_r follows the XSI semantics
+        * not the GNU one. XSI version returns an integer, as opposed to the GNU one
+        * which returns pointer to the buffer.
+        */
+       if (strerror_r (errnum, ebuf, sizeof(ebuf)) == -1) {
+               /* XSI strerror_r will return -1 if errno is set, but if we leave the value
+                * alone it breaks Mono.Posix StdioFileStream tests, so we'll ignore the value
+                * and set errno as below
+                */
+               errno = EINVAL;
+               return -1;
+       }
+       r = ebuf;
+#else
        r = strerror_r (errnum, ebuf, sizeof(ebuf));
+#endif
+       if (!r) {
+               errno = EINVAL;
+               return -1;
+       } 
        len = strlen (r);
 
        if (r == ebuf ||
index 737c217727585521e981daf3f93ed8c7b5eb1f7b..ee61ae661d9be7e741c0997fdf7e6de54ccc5d9a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * This file was automatically generated by create-native-map from /cvs/mono/mcs/class/lib/net_4_5/Mono.Posix.dll.
+ * This file was automatically generated by create-native-map from /home/kiesssn/prog/mono/mono/mcs/class/lib/net_4_x/Mono.Posix.dll.
  *
  * DO NOT MODIFY.
  */
@@ -27,6 +27,9 @@
  */
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif /* ndef HAVE_NETINET_IN_H */
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif /* ndef HAVE_SYS_TIME_H */
@@ -45,6 +48,9 @@
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif /* ndef HAVE_SYS_MMAN_H */
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif /* ndef HAVE_SYS_SOCKET_H */
 #ifdef HAVE_SYS_UIO_H
 #include <sys/uio.h>
 #endif /* ndef HAVE_SYS_UIO_H */
@@ -3115,6 +3121,40 @@ Mono_Posix_ToIovec (struct iovec *from, struct Mono_Posix_Iovec *to)
 #endif /* ndef HAVE_STRUCT_IOVEC */
 
 
+#ifdef HAVE_STRUCT_LINGER
+int
+Mono_Posix_FromLinger (struct Mono_Posix_Linger *from, struct linger *to)
+{
+       _cnm_return_val_if_overflow (int, from->l_onoff, -1);
+       _cnm_return_val_if_overflow (int, from->l_linger, -1);
+
+       memset (to, 0, sizeof(*to));
+
+       to->l_onoff  = from->l_onoff;
+       to->l_linger = from->l_linger;
+
+       return 0;
+}
+#endif /* ndef HAVE_STRUCT_LINGER */
+
+
+#ifdef HAVE_STRUCT_LINGER
+int
+Mono_Posix_ToLinger (struct linger *from, struct Mono_Posix_Linger *to)
+{
+       _cnm_return_val_if_overflow (int, from->l_onoff, -1);
+       _cnm_return_val_if_overflow (int, from->l_linger, -1);
+
+       memset (to, 0, sizeof(*to));
+
+       to->l_onoff  = from->l_onoff;
+       to->l_linger = from->l_linger;
+
+       return 0;
+}
+#endif /* ndef HAVE_STRUCT_LINGER */
+
+
 int Mono_Posix_FromLockType (short x, short *r)
 {
        *r = 0;
@@ -3217,6 +3257,212 @@ int Mono_Posix_ToLockfCommand (int x, int *r)
        errno = EINVAL; return -1;
 }
 
+int Mono_Posix_FromMessageFlags (int x, int *r)
+{
+       *r = 0;
+       if ((x & Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC) == Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC)
+#ifdef MSG_CMSG_CLOEXEC
+               *r |= MSG_CMSG_CLOEXEC;
+#else /* def MSG_CMSG_CLOEXEC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_CMSG_CLOEXEC */
+       if ((x & Mono_Posix_MessageFlags_MSG_CONFIRM) == Mono_Posix_MessageFlags_MSG_CONFIRM)
+#ifdef MSG_CONFIRM
+               *r |= MSG_CONFIRM;
+#else /* def MSG_CONFIRM */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_CONFIRM */
+       if ((x & Mono_Posix_MessageFlags_MSG_CTRUNC) == Mono_Posix_MessageFlags_MSG_CTRUNC)
+#ifdef MSG_CTRUNC
+               *r |= MSG_CTRUNC;
+#else /* def MSG_CTRUNC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_CTRUNC */
+       if ((x & Mono_Posix_MessageFlags_MSG_DONTROUTE) == Mono_Posix_MessageFlags_MSG_DONTROUTE)
+#ifdef MSG_DONTROUTE
+               *r |= MSG_DONTROUTE;
+#else /* def MSG_DONTROUTE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_DONTROUTE */
+       if ((x & Mono_Posix_MessageFlags_MSG_DONTWAIT) == Mono_Posix_MessageFlags_MSG_DONTWAIT)
+#ifdef MSG_DONTWAIT
+               *r |= MSG_DONTWAIT;
+#else /* def MSG_DONTWAIT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_DONTWAIT */
+       if ((x & Mono_Posix_MessageFlags_MSG_EOR) == Mono_Posix_MessageFlags_MSG_EOR)
+#ifdef MSG_EOR
+               *r |= MSG_EOR;
+#else /* def MSG_EOR */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_EOR */
+       if ((x & Mono_Posix_MessageFlags_MSG_ERRQUEUE) == Mono_Posix_MessageFlags_MSG_ERRQUEUE)
+#ifdef MSG_ERRQUEUE
+               *r |= MSG_ERRQUEUE;
+#else /* def MSG_ERRQUEUE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_ERRQUEUE */
+       if ((x & Mono_Posix_MessageFlags_MSG_FASTOPEN) == Mono_Posix_MessageFlags_MSG_FASTOPEN)
+#ifdef MSG_FASTOPEN
+               *r |= MSG_FASTOPEN;
+#else /* def MSG_FASTOPEN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_FASTOPEN */
+       if ((x & Mono_Posix_MessageFlags_MSG_FIN) == Mono_Posix_MessageFlags_MSG_FIN)
+#ifdef MSG_FIN
+               *r |= MSG_FIN;
+#else /* def MSG_FIN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_FIN */
+       if ((x & Mono_Posix_MessageFlags_MSG_MORE) == Mono_Posix_MessageFlags_MSG_MORE)
+#ifdef MSG_MORE
+               *r |= MSG_MORE;
+#else /* def MSG_MORE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_MORE */
+       if ((x & Mono_Posix_MessageFlags_MSG_NOSIGNAL) == Mono_Posix_MessageFlags_MSG_NOSIGNAL)
+#ifdef MSG_NOSIGNAL
+               *r |= MSG_NOSIGNAL;
+#else /* def MSG_NOSIGNAL */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_NOSIGNAL */
+       if ((x & Mono_Posix_MessageFlags_MSG_OOB) == Mono_Posix_MessageFlags_MSG_OOB)
+#ifdef MSG_OOB
+               *r |= MSG_OOB;
+#else /* def MSG_OOB */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_OOB */
+       if ((x & Mono_Posix_MessageFlags_MSG_PEEK) == Mono_Posix_MessageFlags_MSG_PEEK)
+#ifdef MSG_PEEK
+               *r |= MSG_PEEK;
+#else /* def MSG_PEEK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_PEEK */
+       if ((x & Mono_Posix_MessageFlags_MSG_PROXY) == Mono_Posix_MessageFlags_MSG_PROXY)
+#ifdef MSG_PROXY
+               *r |= MSG_PROXY;
+#else /* def MSG_PROXY */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_PROXY */
+       if ((x & Mono_Posix_MessageFlags_MSG_RST) == Mono_Posix_MessageFlags_MSG_RST)
+#ifdef MSG_RST
+               *r |= MSG_RST;
+#else /* def MSG_RST */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_RST */
+       if ((x & Mono_Posix_MessageFlags_MSG_SYN) == Mono_Posix_MessageFlags_MSG_SYN)
+#ifdef MSG_SYN
+               *r |= MSG_SYN;
+#else /* def MSG_SYN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_SYN */
+       if ((x & Mono_Posix_MessageFlags_MSG_TRUNC) == Mono_Posix_MessageFlags_MSG_TRUNC)
+#ifdef MSG_TRUNC
+               *r |= MSG_TRUNC;
+#else /* def MSG_TRUNC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_TRUNC */
+       if ((x & Mono_Posix_MessageFlags_MSG_WAITALL) == Mono_Posix_MessageFlags_MSG_WAITALL)
+#ifdef MSG_WAITALL
+               *r |= MSG_WAITALL;
+#else /* def MSG_WAITALL */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_WAITALL */
+       if ((x & Mono_Posix_MessageFlags_MSG_WAITFORONE) == Mono_Posix_MessageFlags_MSG_WAITFORONE)
+#ifdef MSG_WAITFORONE
+               *r |= MSG_WAITFORONE;
+#else /* def MSG_WAITFORONE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef MSG_WAITFORONE */
+       if (x == 0)
+               return 0;
+       return 0;
+}
+
+int Mono_Posix_ToMessageFlags (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef MSG_CMSG_CLOEXEC
+       if ((x & MSG_CMSG_CLOEXEC) == MSG_CMSG_CLOEXEC)
+               *r |= Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC;
+#endif /* ndef MSG_CMSG_CLOEXEC */
+#ifdef MSG_CONFIRM
+       if ((x & MSG_CONFIRM) == MSG_CONFIRM)
+               *r |= Mono_Posix_MessageFlags_MSG_CONFIRM;
+#endif /* ndef MSG_CONFIRM */
+#ifdef MSG_CTRUNC
+       if ((x & MSG_CTRUNC) == MSG_CTRUNC)
+               *r |= Mono_Posix_MessageFlags_MSG_CTRUNC;
+#endif /* ndef MSG_CTRUNC */
+#ifdef MSG_DONTROUTE
+       if ((x & MSG_DONTROUTE) == MSG_DONTROUTE)
+               *r |= Mono_Posix_MessageFlags_MSG_DONTROUTE;
+#endif /* ndef MSG_DONTROUTE */
+#ifdef MSG_DONTWAIT
+       if ((x & MSG_DONTWAIT) == MSG_DONTWAIT)
+               *r |= Mono_Posix_MessageFlags_MSG_DONTWAIT;
+#endif /* ndef MSG_DONTWAIT */
+#ifdef MSG_EOR
+       if ((x & MSG_EOR) == MSG_EOR)
+               *r |= Mono_Posix_MessageFlags_MSG_EOR;
+#endif /* ndef MSG_EOR */
+#ifdef MSG_ERRQUEUE
+       if ((x & MSG_ERRQUEUE) == MSG_ERRQUEUE)
+               *r |= Mono_Posix_MessageFlags_MSG_ERRQUEUE;
+#endif /* ndef MSG_ERRQUEUE */
+#ifdef MSG_FASTOPEN
+       if ((x & MSG_FASTOPEN) == MSG_FASTOPEN)
+               *r |= Mono_Posix_MessageFlags_MSG_FASTOPEN;
+#endif /* ndef MSG_FASTOPEN */
+#ifdef MSG_FIN
+       if ((x & MSG_FIN) == MSG_FIN)
+               *r |= Mono_Posix_MessageFlags_MSG_FIN;
+#endif /* ndef MSG_FIN */
+#ifdef MSG_MORE
+       if ((x & MSG_MORE) == MSG_MORE)
+               *r |= Mono_Posix_MessageFlags_MSG_MORE;
+#endif /* ndef MSG_MORE */
+#ifdef MSG_NOSIGNAL
+       if ((x & MSG_NOSIGNAL) == MSG_NOSIGNAL)
+               *r |= Mono_Posix_MessageFlags_MSG_NOSIGNAL;
+#endif /* ndef MSG_NOSIGNAL */
+#ifdef MSG_OOB
+       if ((x & MSG_OOB) == MSG_OOB)
+               *r |= Mono_Posix_MessageFlags_MSG_OOB;
+#endif /* ndef MSG_OOB */
+#ifdef MSG_PEEK
+       if ((x & MSG_PEEK) == MSG_PEEK)
+               *r |= Mono_Posix_MessageFlags_MSG_PEEK;
+#endif /* ndef MSG_PEEK */
+#ifdef MSG_PROXY
+       if ((x & MSG_PROXY) == MSG_PROXY)
+               *r |= Mono_Posix_MessageFlags_MSG_PROXY;
+#endif /* ndef MSG_PROXY */
+#ifdef MSG_RST
+       if ((x & MSG_RST) == MSG_RST)
+               *r |= Mono_Posix_MessageFlags_MSG_RST;
+#endif /* ndef MSG_RST */
+#ifdef MSG_SYN
+       if ((x & MSG_SYN) == MSG_SYN)
+               *r |= Mono_Posix_MessageFlags_MSG_SYN;
+#endif /* ndef MSG_SYN */
+#ifdef MSG_TRUNC
+       if ((x & MSG_TRUNC) == MSG_TRUNC)
+               *r |= Mono_Posix_MessageFlags_MSG_TRUNC;
+#endif /* ndef MSG_TRUNC */
+#ifdef MSG_WAITALL
+       if ((x & MSG_WAITALL) == MSG_WAITALL)
+               *r |= Mono_Posix_MessageFlags_MSG_WAITALL;
+#endif /* ndef MSG_WAITALL */
+#ifdef MSG_WAITFORONE
+       if ((x & MSG_WAITFORONE) == MSG_WAITFORONE)
+               *r |= Mono_Posix_MessageFlags_MSG_WAITFORONE;
+#endif /* ndef MSG_WAITFORONE */
+       return 0;
+}
+
 int Mono_Posix_FromMlockallFlags (int x, int *r)
 {
        *r = 0;
@@ -4491,6 +4737,52 @@ int Mono_Posix_ToSeekFlags (short x, short *r)
        errno = EINVAL; return -1;
 }
 
+int Mono_Posix_FromShutdownOption (int x, int *r)
+{
+       *r = 0;
+       if (x == Mono_Posix_ShutdownOption_SHUT_RD)
+#ifdef SHUT_RD
+               {*r = SHUT_RD; return 0;}
+#else /* def SHUT_RD */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SHUT_RD */
+       if (x == Mono_Posix_ShutdownOption_SHUT_RDWR)
+#ifdef SHUT_RDWR
+               {*r = SHUT_RDWR; return 0;}
+#else /* def SHUT_RDWR */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SHUT_RDWR */
+       if (x == Mono_Posix_ShutdownOption_SHUT_WR)
+#ifdef SHUT_WR
+               {*r = SHUT_WR; return 0;}
+#else /* def SHUT_WR */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SHUT_WR */
+       if (x == 0)
+               return 0;
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToShutdownOption (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef SHUT_RD
+       if (x == SHUT_RD)
+               {*r = Mono_Posix_ShutdownOption_SHUT_RD; return 0;}
+#endif /* ndef SHUT_RD */
+#ifdef SHUT_RDWR
+       if (x == SHUT_RDWR)
+               {*r = Mono_Posix_ShutdownOption_SHUT_RDWR; return 0;}
+#endif /* ndef SHUT_RDWR */
+#ifdef SHUT_WR
+       if (x == SHUT_WR)
+               {*r = Mono_Posix_ShutdownOption_SHUT_WR; return 0;}
+#endif /* ndef SHUT_WR */
+       errno = EINVAL; return -1;
+}
+
 int Mono_Posix_FromSignum (int x, int *r)
 {
        *r = 0;
@@ -7373,6 +7665,1286 @@ Mono_Posix_ToTimezone (struct timezone *from, struct Mono_Posix_Timezone *to)
 #endif /* ndef HAVE_STRUCT_TIMEZONE */
 
 
+int Mono_Posix_FromUnixAddressFamily (int x, int *r)
+{
+       *r = 0;
+       if (x == Mono_Posix_UnixAddressFamily_AF_ALG)
+#ifdef AF_ALG
+               {*r = AF_ALG; return 0;}
+#else /* def AF_ALG */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ALG */
+       if (x == Mono_Posix_UnixAddressFamily_AF_APPLETALK)
+#ifdef AF_APPLETALK
+               {*r = AF_APPLETALK; return 0;}
+#else /* def AF_APPLETALK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_APPLETALK */
+       if (x == Mono_Posix_UnixAddressFamily_AF_ASH)
+#ifdef AF_ASH
+               {*r = AF_ASH; return 0;}
+#else /* def AF_ASH */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ASH */
+       if (x == Mono_Posix_UnixAddressFamily_AF_ATMPVC)
+#ifdef AF_ATMPVC
+               {*r = AF_ATMPVC; return 0;}
+#else /* def AF_ATMPVC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ATMPVC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_ATMSVC)
+#ifdef AF_ATMSVC
+               {*r = AF_ATMSVC; return 0;}
+#else /* def AF_ATMSVC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ATMSVC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_AX25)
+#ifdef AF_AX25
+               {*r = AF_AX25; return 0;}
+#else /* def AF_AX25 */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_AX25 */
+       if (x == Mono_Posix_UnixAddressFamily_AF_BLUETOOTH)
+#ifdef AF_BLUETOOTH
+               {*r = AF_BLUETOOTH; return 0;}
+#else /* def AF_BLUETOOTH */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_BLUETOOTH */
+       if (x == Mono_Posix_UnixAddressFamily_AF_BRIDGE)
+#ifdef AF_BRIDGE
+               {*r = AF_BRIDGE; return 0;}
+#else /* def AF_BRIDGE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_BRIDGE */
+       if (x == Mono_Posix_UnixAddressFamily_AF_CAIF)
+#ifdef AF_CAIF
+               {*r = AF_CAIF; return 0;}
+#else /* def AF_CAIF */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_CAIF */
+       if (x == Mono_Posix_UnixAddressFamily_AF_CAN)
+#ifdef AF_CAN
+               {*r = AF_CAN; return 0;}
+#else /* def AF_CAN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_CAN */
+       if (x == Mono_Posix_UnixAddressFamily_AF_DECnet)
+#ifdef AF_DECnet
+               {*r = AF_DECnet; return 0;}
+#else /* def AF_DECnet */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_DECnet */
+       if (x == Mono_Posix_UnixAddressFamily_AF_ECONET)
+#ifdef AF_ECONET
+               {*r = AF_ECONET; return 0;}
+#else /* def AF_ECONET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ECONET */
+       if (x == Mono_Posix_UnixAddressFamily_AF_IEEE802154)
+#ifdef AF_IEEE802154
+               {*r = AF_IEEE802154; return 0;}
+#else /* def AF_IEEE802154 */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_IEEE802154 */
+       if (x == Mono_Posix_UnixAddressFamily_AF_INET)
+#ifdef AF_INET
+               {*r = AF_INET; return 0;}
+#else /* def AF_INET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_INET */
+       if (x == Mono_Posix_UnixAddressFamily_AF_INET6)
+#ifdef AF_INET6
+               {*r = AF_INET6; return 0;}
+#else /* def AF_INET6 */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_INET6 */
+       if (x == Mono_Posix_UnixAddressFamily_AF_IPX)
+#ifdef AF_IPX
+               {*r = AF_IPX; return 0;}
+#else /* def AF_IPX */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_IPX */
+       if (x == Mono_Posix_UnixAddressFamily_AF_IRDA)
+#ifdef AF_IRDA
+               {*r = AF_IRDA; return 0;}
+#else /* def AF_IRDA */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_IRDA */
+       if (x == Mono_Posix_UnixAddressFamily_AF_ISDN)
+#ifdef AF_ISDN
+               {*r = AF_ISDN; return 0;}
+#else /* def AF_ISDN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ISDN */
+       if (x == Mono_Posix_UnixAddressFamily_AF_IUCV)
+#ifdef AF_IUCV
+               {*r = AF_IUCV; return 0;}
+#else /* def AF_IUCV */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_IUCV */
+       if (x == Mono_Posix_UnixAddressFamily_AF_KEY)
+#ifdef AF_KEY
+               {*r = AF_KEY; return 0;}
+#else /* def AF_KEY */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_KEY */
+       if (x == Mono_Posix_UnixAddressFamily_AF_LLC)
+#ifdef AF_LLC
+               {*r = AF_LLC; return 0;}
+#else /* def AF_LLC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_LLC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_NETBEUI)
+#ifdef AF_NETBEUI
+               {*r = AF_NETBEUI; return 0;}
+#else /* def AF_NETBEUI */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_NETBEUI */
+       if (x == Mono_Posix_UnixAddressFamily_AF_NETLINK)
+#ifdef AF_NETLINK
+               {*r = AF_NETLINK; return 0;}
+#else /* def AF_NETLINK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_NETLINK */
+       if (x == Mono_Posix_UnixAddressFamily_AF_NETROM)
+#ifdef AF_NETROM
+               {*r = AF_NETROM; return 0;}
+#else /* def AF_NETROM */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_NETROM */
+       if (x == Mono_Posix_UnixAddressFamily_AF_NFC)
+#ifdef AF_NFC
+               {*r = AF_NFC; return 0;}
+#else /* def AF_NFC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_NFC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_PACKET)
+#ifdef AF_PACKET
+               {*r = AF_PACKET; return 0;}
+#else /* def AF_PACKET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_PACKET */
+       if (x == Mono_Posix_UnixAddressFamily_AF_PHONET)
+#ifdef AF_PHONET
+               {*r = AF_PHONET; return 0;}
+#else /* def AF_PHONET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_PHONET */
+       if (x == Mono_Posix_UnixAddressFamily_AF_PPPOX)
+#ifdef AF_PPPOX
+               {*r = AF_PPPOX; return 0;}
+#else /* def AF_PPPOX */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_PPPOX */
+       if (x == Mono_Posix_UnixAddressFamily_AF_RDS)
+#ifdef AF_RDS
+               {*r = AF_RDS; return 0;}
+#else /* def AF_RDS */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_RDS */
+       if (x == Mono_Posix_UnixAddressFamily_AF_ROSE)
+#ifdef AF_ROSE
+               {*r = AF_ROSE; return 0;}
+#else /* def AF_ROSE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_ROSE */
+       if (x == Mono_Posix_UnixAddressFamily_AF_RXRPC)
+#ifdef AF_RXRPC
+               {*r = AF_RXRPC; return 0;}
+#else /* def AF_RXRPC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_RXRPC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_SECURITY)
+#ifdef AF_SECURITY
+               {*r = AF_SECURITY; return 0;}
+#else /* def AF_SECURITY */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_SECURITY */
+       if (x == Mono_Posix_UnixAddressFamily_AF_SNA)
+#ifdef AF_SNA
+               {*r = AF_SNA; return 0;}
+#else /* def AF_SNA */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_SNA */
+       if (x == Mono_Posix_UnixAddressFamily_AF_TIPC)
+#ifdef AF_TIPC
+               {*r = AF_TIPC; return 0;}
+#else /* def AF_TIPC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_TIPC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_UNIX)
+#ifdef AF_UNIX
+               {*r = AF_UNIX; return 0;}
+#else /* def AF_UNIX */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_UNIX */
+       if (x == Mono_Posix_UnixAddressFamily_AF_UNSPEC)
+#ifdef AF_UNSPEC
+               {*r = AF_UNSPEC; return 0;}
+#else /* def AF_UNSPEC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_UNSPEC */
+       if (x == Mono_Posix_UnixAddressFamily_AF_VSOCK)
+#ifdef AF_VSOCK
+               {*r = AF_VSOCK; return 0;}
+#else /* def AF_VSOCK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_VSOCK */
+       if (x == Mono_Posix_UnixAddressFamily_AF_WANPIPE)
+#ifdef AF_WANPIPE
+               {*r = AF_WANPIPE; return 0;}
+#else /* def AF_WANPIPE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_WANPIPE */
+       if (x == Mono_Posix_UnixAddressFamily_AF_X25)
+#ifdef AF_X25
+               {*r = AF_X25; return 0;}
+#else /* def AF_X25 */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AF_X25 */
+       if (x == 0)
+               return 0;
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixAddressFamily (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef AF_ALG
+       if (x == AF_ALG)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ALG; return 0;}
+#endif /* ndef AF_ALG */
+#ifdef AF_APPLETALK
+       if (x == AF_APPLETALK)
+               {*r = Mono_Posix_UnixAddressFamily_AF_APPLETALK; return 0;}
+#endif /* ndef AF_APPLETALK */
+#ifdef AF_ASH
+       if (x == AF_ASH)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ASH; return 0;}
+#endif /* ndef AF_ASH */
+#ifdef AF_ATMPVC
+       if (x == AF_ATMPVC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ATMPVC; return 0;}
+#endif /* ndef AF_ATMPVC */
+#ifdef AF_ATMSVC
+       if (x == AF_ATMSVC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ATMSVC; return 0;}
+#endif /* ndef AF_ATMSVC */
+#ifdef AF_AX25
+       if (x == AF_AX25)
+               {*r = Mono_Posix_UnixAddressFamily_AF_AX25; return 0;}
+#endif /* ndef AF_AX25 */
+#ifdef AF_BLUETOOTH
+       if (x == AF_BLUETOOTH)
+               {*r = Mono_Posix_UnixAddressFamily_AF_BLUETOOTH; return 0;}
+#endif /* ndef AF_BLUETOOTH */
+#ifdef AF_BRIDGE
+       if (x == AF_BRIDGE)
+               {*r = Mono_Posix_UnixAddressFamily_AF_BRIDGE; return 0;}
+#endif /* ndef AF_BRIDGE */
+#ifdef AF_CAIF
+       if (x == AF_CAIF)
+               {*r = Mono_Posix_UnixAddressFamily_AF_CAIF; return 0;}
+#endif /* ndef AF_CAIF */
+#ifdef AF_CAN
+       if (x == AF_CAN)
+               {*r = Mono_Posix_UnixAddressFamily_AF_CAN; return 0;}
+#endif /* ndef AF_CAN */
+#ifdef AF_DECnet
+       if (x == AF_DECnet)
+               {*r = Mono_Posix_UnixAddressFamily_AF_DECnet; return 0;}
+#endif /* ndef AF_DECnet */
+#ifdef AF_ECONET
+       if (x == AF_ECONET)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ECONET; return 0;}
+#endif /* ndef AF_ECONET */
+#ifdef AF_IEEE802154
+       if (x == AF_IEEE802154)
+               {*r = Mono_Posix_UnixAddressFamily_AF_IEEE802154; return 0;}
+#endif /* ndef AF_IEEE802154 */
+#ifdef AF_INET
+       if (x == AF_INET)
+               {*r = Mono_Posix_UnixAddressFamily_AF_INET; return 0;}
+#endif /* ndef AF_INET */
+#ifdef AF_INET6
+       if (x == AF_INET6)
+               {*r = Mono_Posix_UnixAddressFamily_AF_INET6; return 0;}
+#endif /* ndef AF_INET6 */
+#ifdef AF_IPX
+       if (x == AF_IPX)
+               {*r = Mono_Posix_UnixAddressFamily_AF_IPX; return 0;}
+#endif /* ndef AF_IPX */
+#ifdef AF_IRDA
+       if (x == AF_IRDA)
+               {*r = Mono_Posix_UnixAddressFamily_AF_IRDA; return 0;}
+#endif /* ndef AF_IRDA */
+#ifdef AF_ISDN
+       if (x == AF_ISDN)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ISDN; return 0;}
+#endif /* ndef AF_ISDN */
+#ifdef AF_IUCV
+       if (x == AF_IUCV)
+               {*r = Mono_Posix_UnixAddressFamily_AF_IUCV; return 0;}
+#endif /* ndef AF_IUCV */
+#ifdef AF_KEY
+       if (x == AF_KEY)
+               {*r = Mono_Posix_UnixAddressFamily_AF_KEY; return 0;}
+#endif /* ndef AF_KEY */
+#ifdef AF_LLC
+       if (x == AF_LLC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_LLC; return 0;}
+#endif /* ndef AF_LLC */
+#ifdef AF_NETBEUI
+       if (x == AF_NETBEUI)
+               {*r = Mono_Posix_UnixAddressFamily_AF_NETBEUI; return 0;}
+#endif /* ndef AF_NETBEUI */
+#ifdef AF_NETLINK
+       if (x == AF_NETLINK)
+               {*r = Mono_Posix_UnixAddressFamily_AF_NETLINK; return 0;}
+#endif /* ndef AF_NETLINK */
+#ifdef AF_NETROM
+       if (x == AF_NETROM)
+               {*r = Mono_Posix_UnixAddressFamily_AF_NETROM; return 0;}
+#endif /* ndef AF_NETROM */
+#ifdef AF_NFC
+       if (x == AF_NFC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_NFC; return 0;}
+#endif /* ndef AF_NFC */
+#ifdef AF_PACKET
+       if (x == AF_PACKET)
+               {*r = Mono_Posix_UnixAddressFamily_AF_PACKET; return 0;}
+#endif /* ndef AF_PACKET */
+#ifdef AF_PHONET
+       if (x == AF_PHONET)
+               {*r = Mono_Posix_UnixAddressFamily_AF_PHONET; return 0;}
+#endif /* ndef AF_PHONET */
+#ifdef AF_PPPOX
+       if (x == AF_PPPOX)
+               {*r = Mono_Posix_UnixAddressFamily_AF_PPPOX; return 0;}
+#endif /* ndef AF_PPPOX */
+#ifdef AF_RDS
+       if (x == AF_RDS)
+               {*r = Mono_Posix_UnixAddressFamily_AF_RDS; return 0;}
+#endif /* ndef AF_RDS */
+#ifdef AF_ROSE
+       if (x == AF_ROSE)
+               {*r = Mono_Posix_UnixAddressFamily_AF_ROSE; return 0;}
+#endif /* ndef AF_ROSE */
+#ifdef AF_RXRPC
+       if (x == AF_RXRPC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_RXRPC; return 0;}
+#endif /* ndef AF_RXRPC */
+#ifdef AF_SECURITY
+       if (x == AF_SECURITY)
+               {*r = Mono_Posix_UnixAddressFamily_AF_SECURITY; return 0;}
+#endif /* ndef AF_SECURITY */
+#ifdef AF_SNA
+       if (x == AF_SNA)
+               {*r = Mono_Posix_UnixAddressFamily_AF_SNA; return 0;}
+#endif /* ndef AF_SNA */
+#ifdef AF_TIPC
+       if (x == AF_TIPC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_TIPC; return 0;}
+#endif /* ndef AF_TIPC */
+#ifdef AF_UNIX
+       if (x == AF_UNIX)
+               {*r = Mono_Posix_UnixAddressFamily_AF_UNIX; return 0;}
+#endif /* ndef AF_UNIX */
+#ifdef AF_UNSPEC
+       if (x == AF_UNSPEC)
+               {*r = Mono_Posix_UnixAddressFamily_AF_UNSPEC; return 0;}
+#endif /* ndef AF_UNSPEC */
+#ifdef AF_VSOCK
+       if (x == AF_VSOCK)
+               {*r = Mono_Posix_UnixAddressFamily_AF_VSOCK; return 0;}
+#endif /* ndef AF_VSOCK */
+#ifdef AF_WANPIPE
+       if (x == AF_WANPIPE)
+               {*r = Mono_Posix_UnixAddressFamily_AF_WANPIPE; return 0;}
+#endif /* ndef AF_WANPIPE */
+#ifdef AF_X25
+       if (x == AF_X25)
+               {*r = Mono_Posix_UnixAddressFamily_AF_X25; return 0;}
+#endif /* ndef AF_X25 */
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_FromUnixSocketFlags (int x, int *r)
+{
+       *r = 0;
+       if ((x & Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC) == Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC)
+#ifdef SOCK_CLOEXEC
+               *r |= SOCK_CLOEXEC;
+#else /* def SOCK_CLOEXEC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_CLOEXEC */
+       if ((x & Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK) == Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK)
+#ifdef SOCK_NONBLOCK
+               *r |= SOCK_NONBLOCK;
+#else /* def SOCK_NONBLOCK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_NONBLOCK */
+       if (x == 0)
+               return 0;
+       return 0;
+}
+
+int Mono_Posix_ToUnixSocketFlags (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef SOCK_CLOEXEC
+       if ((x & SOCK_CLOEXEC) == SOCK_CLOEXEC)
+               *r |= Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC;
+#endif /* ndef SOCK_CLOEXEC */
+#ifdef SOCK_NONBLOCK
+       if ((x & SOCK_NONBLOCK) == SOCK_NONBLOCK)
+               *r |= Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK;
+#endif /* ndef SOCK_NONBLOCK */
+       return 0;
+}
+
+int Mono_Posix_FromUnixSocketOptionName (int x, int *r)
+{
+       *r = 0;
+       if (x == Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN)
+#ifdef SO_ACCEPTCONN
+               {*r = SO_ACCEPTCONN; return 0;}
+#else /* def SO_ACCEPTCONN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_ACCEPTCONN */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER)
+#ifdef SO_ATTACH_FILTER
+               {*r = SO_ATTACH_FILTER; return 0;}
+#else /* def SO_ATTACH_FILTER */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_ATTACH_FILTER */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE)
+#ifdef SO_BINDTODEVICE
+               {*r = SO_BINDTODEVICE; return 0;}
+#else /* def SO_BINDTODEVICE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_BINDTODEVICE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_BROADCAST)
+#ifdef SO_BROADCAST
+               {*r = SO_BROADCAST; return 0;}
+#else /* def SO_BROADCAST */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_BROADCAST */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT)
+#ifdef SO_BSDCOMPAT
+               {*r = SO_BSDCOMPAT; return 0;}
+#else /* def SO_BSDCOMPAT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_BSDCOMPAT */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL)
+#ifdef SO_BUSY_POLL
+               {*r = SO_BUSY_POLL; return 0;}
+#else /* def SO_BUSY_POLL */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_BUSY_POLL */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_DEBUG)
+#ifdef SO_DEBUG
+               {*r = SO_DEBUG; return 0;}
+#else /* def SO_DEBUG */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_DEBUG */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER)
+#ifdef SO_DETACH_FILTER
+               {*r = SO_DETACH_FILTER; return 0;}
+#else /* def SO_DETACH_FILTER */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_DETACH_FILTER */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_DOMAIN)
+#ifdef SO_DOMAIN
+               {*r = SO_DOMAIN; return 0;}
+#else /* def SO_DOMAIN */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_DOMAIN */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_DONTROUTE)
+#ifdef SO_DONTROUTE
+               {*r = SO_DONTROUTE; return 0;}
+#else /* def SO_DONTROUTE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_DONTROUTE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_ERROR)
+#ifdef SO_ERROR
+               {*r = SO_ERROR; return 0;}
+#else /* def SO_ERROR */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_ERROR */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE)
+#ifdef SO_KEEPALIVE
+               {*r = SO_KEEPALIVE; return 0;}
+#else /* def SO_KEEPALIVE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_KEEPALIVE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_LINGER)
+#ifdef SO_LINGER
+               {*r = SO_LINGER; return 0;}
+#else /* def SO_LINGER */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_LINGER */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER)
+#ifdef SO_LOCK_FILTER
+               {*r = SO_LOCK_FILTER; return 0;}
+#else /* def SO_LOCK_FILTER */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_LOCK_FILTER */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_MARK)
+#ifdef SO_MARK
+               {*r = SO_MARK; return 0;}
+#else /* def SO_MARK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_MARK */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE)
+#ifdef SO_MAX_PACING_RATE
+               {*r = SO_MAX_PACING_RATE; return 0;}
+#else /* def SO_MAX_PACING_RATE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_MAX_PACING_RATE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_NOFCS)
+#ifdef SO_NOFCS
+               {*r = SO_NOFCS; return 0;}
+#else /* def SO_NOFCS */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_NOFCS */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_NO_CHECK)
+#ifdef SO_NO_CHECK
+               {*r = SO_NO_CHECK; return 0;}
+#else /* def SO_NO_CHECK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_NO_CHECK */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_OOBINLINE)
+#ifdef SO_OOBINLINE
+               {*r = SO_OOBINLINE; return 0;}
+#else /* def SO_OOBINLINE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_OOBINLINE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PASSCRED)
+#ifdef SO_PASSCRED
+               {*r = SO_PASSCRED; return 0;}
+#else /* def SO_PASSCRED */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PASSCRED */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PASSSEC)
+#ifdef SO_PASSSEC
+               {*r = SO_PASSSEC; return 0;}
+#else /* def SO_PASSSEC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PASSSEC */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF)
+#ifdef SO_PEEK_OFF
+               {*r = SO_PEEK_OFF; return 0;}
+#else /* def SO_PEEK_OFF */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEEK_OFF */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PEERCRED)
+#ifdef SO_PEERCRED
+               {*r = SO_PEERCRED; return 0;}
+#else /* def SO_PEERCRED */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEERCRED */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PEERNAME)
+#ifdef SO_PEERNAME
+               {*r = SO_PEERNAME; return 0;}
+#else /* def SO_PEERNAME */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEERNAME */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PEERSEC)
+#ifdef SO_PEERSEC
+               {*r = SO_PEERSEC; return 0;}
+#else /* def SO_PEERSEC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEERSEC */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PRIORITY)
+#ifdef SO_PRIORITY
+               {*r = SO_PRIORITY; return 0;}
+#else /* def SO_PRIORITY */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PRIORITY */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_PROTOCOL)
+#ifdef SO_PROTOCOL
+               {*r = SO_PROTOCOL; return 0;}
+#else /* def SO_PROTOCOL */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_PROTOCOL */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_RCVBUF)
+#ifdef SO_RCVBUF
+               {*r = SO_RCVBUF; return 0;}
+#else /* def SO_RCVBUF */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVBUF */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE)
+#ifdef SO_RCVBUFFORCE
+               {*r = SO_RCVBUFFORCE; return 0;}
+#else /* def SO_RCVBUFFORCE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVBUFFORCE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT)
+#ifdef SO_RCVLOWAT
+               {*r = SO_RCVLOWAT; return 0;}
+#else /* def SO_RCVLOWAT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVLOWAT */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO)
+#ifdef SO_RCVTIMEO
+               {*r = SO_RCVTIMEO; return 0;}
+#else /* def SO_RCVTIMEO */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVTIMEO */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_REUSEADDR)
+#ifdef SO_REUSEADDR
+               {*r = SO_REUSEADDR; return 0;}
+#else /* def SO_REUSEADDR */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_REUSEADDR */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_REUSEPORT)
+#ifdef SO_REUSEPORT
+               {*r = SO_REUSEPORT; return 0;}
+#else /* def SO_REUSEPORT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_REUSEPORT */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL)
+#ifdef SO_RXQ_OVFL
+               {*r = SO_RXQ_OVFL; return 0;}
+#else /* def SO_RXQ_OVFL */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_RXQ_OVFL */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION)
+#ifdef SO_SECURITY_AUTHENTICATION
+               {*r = SO_SECURITY_AUTHENTICATION; return 0;}
+#else /* def SO_SECURITY_AUTHENTICATION */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SECURITY_AUTHENTICATION */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK)
+#ifdef SO_SECURITY_ENCRYPTION_NETWORK
+               {*r = SO_SECURITY_ENCRYPTION_NETWORK; return 0;}
+#else /* def SO_SECURITY_ENCRYPTION_NETWORK */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_NETWORK */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT)
+#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
+               {*r = SO_SECURITY_ENCRYPTION_TRANSPORT; return 0;}
+#else /* def SO_SECURITY_ENCRYPTION_TRANSPORT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_TRANSPORT */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE)
+#ifdef SO_SELECT_ERR_QUEUE
+               {*r = SO_SELECT_ERR_QUEUE; return 0;}
+#else /* def SO_SELECT_ERR_QUEUE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SELECT_ERR_QUEUE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SNDBUF)
+#ifdef SO_SNDBUF
+               {*r = SO_SNDBUF; return 0;}
+#else /* def SO_SNDBUF */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDBUF */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE)
+#ifdef SO_SNDBUFFORCE
+               {*r = SO_SNDBUFFORCE; return 0;}
+#else /* def SO_SNDBUFFORCE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDBUFFORCE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT)
+#ifdef SO_SNDLOWAT
+               {*r = SO_SNDLOWAT; return 0;}
+#else /* def SO_SNDLOWAT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDLOWAT */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO)
+#ifdef SO_SNDTIMEO
+               {*r = SO_SNDTIMEO; return 0;}
+#else /* def SO_SNDTIMEO */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDTIMEO */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP)
+#ifdef SO_TIMESTAMP
+               {*r = SO_TIMESTAMP; return 0;}
+#else /* def SO_TIMESTAMP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_TIMESTAMP */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING)
+#ifdef SO_TIMESTAMPING
+               {*r = SO_TIMESTAMPING; return 0;}
+#else /* def SO_TIMESTAMPING */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_TIMESTAMPING */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS)
+#ifdef SO_TIMESTAMPNS
+               {*r = SO_TIMESTAMPNS; return 0;}
+#else /* def SO_TIMESTAMPNS */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_TIMESTAMPNS */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_TYPE)
+#ifdef SO_TYPE
+               {*r = SO_TYPE; return 0;}
+#else /* def SO_TYPE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_TYPE */
+       if (x == Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS)
+#ifdef SO_WIFI_STATUS
+               {*r = SO_WIFI_STATUS; return 0;}
+#else /* def SO_WIFI_STATUS */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SO_WIFI_STATUS */
+       if (x == 0)
+               return 0;
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixSocketOptionName (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef SO_ACCEPTCONN
+       if (x == SO_ACCEPTCONN)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN; return 0;}
+#endif /* ndef SO_ACCEPTCONN */
+#ifdef SO_ATTACH_FILTER
+       if (x == SO_ATTACH_FILTER)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER; return 0;}
+#endif /* ndef SO_ATTACH_FILTER */
+#ifdef SO_BINDTODEVICE
+       if (x == SO_BINDTODEVICE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE; return 0;}
+#endif /* ndef SO_BINDTODEVICE */
+#ifdef SO_BROADCAST
+       if (x == SO_BROADCAST)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_BROADCAST; return 0;}
+#endif /* ndef SO_BROADCAST */
+#ifdef SO_BSDCOMPAT
+       if (x == SO_BSDCOMPAT)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT; return 0;}
+#endif /* ndef SO_BSDCOMPAT */
+#ifdef SO_BUSY_POLL
+       if (x == SO_BUSY_POLL)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL; return 0;}
+#endif /* ndef SO_BUSY_POLL */
+#ifdef SO_DEBUG
+       if (x == SO_DEBUG)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_DEBUG; return 0;}
+#endif /* ndef SO_DEBUG */
+#ifdef SO_DETACH_FILTER
+       if (x == SO_DETACH_FILTER)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER; return 0;}
+#endif /* ndef SO_DETACH_FILTER */
+#ifdef SO_DOMAIN
+       if (x == SO_DOMAIN)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_DOMAIN; return 0;}
+#endif /* ndef SO_DOMAIN */
+#ifdef SO_DONTROUTE
+       if (x == SO_DONTROUTE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_DONTROUTE; return 0;}
+#endif /* ndef SO_DONTROUTE */
+#ifdef SO_ERROR
+       if (x == SO_ERROR)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_ERROR; return 0;}
+#endif /* ndef SO_ERROR */
+#ifdef SO_KEEPALIVE
+       if (x == SO_KEEPALIVE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE; return 0;}
+#endif /* ndef SO_KEEPALIVE */
+#ifdef SO_LINGER
+       if (x == SO_LINGER)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_LINGER; return 0;}
+#endif /* ndef SO_LINGER */
+#ifdef SO_LOCK_FILTER
+       if (x == SO_LOCK_FILTER)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER; return 0;}
+#endif /* ndef SO_LOCK_FILTER */
+#ifdef SO_MARK
+       if (x == SO_MARK)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_MARK; return 0;}
+#endif /* ndef SO_MARK */
+#ifdef SO_MAX_PACING_RATE
+       if (x == SO_MAX_PACING_RATE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE; return 0;}
+#endif /* ndef SO_MAX_PACING_RATE */
+#ifdef SO_NOFCS
+       if (x == SO_NOFCS)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_NOFCS; return 0;}
+#endif /* ndef SO_NOFCS */
+#ifdef SO_NO_CHECK
+       if (x == SO_NO_CHECK)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_NO_CHECK; return 0;}
+#endif /* ndef SO_NO_CHECK */
+#ifdef SO_OOBINLINE
+       if (x == SO_OOBINLINE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_OOBINLINE; return 0;}
+#endif /* ndef SO_OOBINLINE */
+#ifdef SO_PASSCRED
+       if (x == SO_PASSCRED)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PASSCRED; return 0;}
+#endif /* ndef SO_PASSCRED */
+#ifdef SO_PASSSEC
+       if (x == SO_PASSSEC)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PASSSEC; return 0;}
+#endif /* ndef SO_PASSSEC */
+#ifdef SO_PEEK_OFF
+       if (x == SO_PEEK_OFF)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF; return 0;}
+#endif /* ndef SO_PEEK_OFF */
+#ifdef SO_PEERCRED
+       if (x == SO_PEERCRED)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PEERCRED; return 0;}
+#endif /* ndef SO_PEERCRED */
+#ifdef SO_PEERNAME
+       if (x == SO_PEERNAME)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PEERNAME; return 0;}
+#endif /* ndef SO_PEERNAME */
+#ifdef SO_PEERSEC
+       if (x == SO_PEERSEC)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PEERSEC; return 0;}
+#endif /* ndef SO_PEERSEC */
+#ifdef SO_PRIORITY
+       if (x == SO_PRIORITY)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PRIORITY; return 0;}
+#endif /* ndef SO_PRIORITY */
+#ifdef SO_PROTOCOL
+       if (x == SO_PROTOCOL)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_PROTOCOL; return 0;}
+#endif /* ndef SO_PROTOCOL */
+#ifdef SO_RCVBUF
+       if (x == SO_RCVBUF)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_RCVBUF; return 0;}
+#endif /* ndef SO_RCVBUF */
+#ifdef SO_RCVBUFFORCE
+       if (x == SO_RCVBUFFORCE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE; return 0;}
+#endif /* ndef SO_RCVBUFFORCE */
+#ifdef SO_RCVLOWAT
+       if (x == SO_RCVLOWAT)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT; return 0;}
+#endif /* ndef SO_RCVLOWAT */
+#ifdef SO_RCVTIMEO
+       if (x == SO_RCVTIMEO)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO; return 0;}
+#endif /* ndef SO_RCVTIMEO */
+#ifdef SO_REUSEADDR
+       if (x == SO_REUSEADDR)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_REUSEADDR; return 0;}
+#endif /* ndef SO_REUSEADDR */
+#ifdef SO_REUSEPORT
+       if (x == SO_REUSEPORT)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_REUSEPORT; return 0;}
+#endif /* ndef SO_REUSEPORT */
+#ifdef SO_RXQ_OVFL
+       if (x == SO_RXQ_OVFL)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL; return 0;}
+#endif /* ndef SO_RXQ_OVFL */
+#ifdef SO_SECURITY_AUTHENTICATION
+       if (x == SO_SECURITY_AUTHENTICATION)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION; return 0;}
+#endif /* ndef SO_SECURITY_AUTHENTICATION */
+#ifdef SO_SECURITY_ENCRYPTION_NETWORK
+       if (x == SO_SECURITY_ENCRYPTION_NETWORK)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK; return 0;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_NETWORK */
+#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
+       if (x == SO_SECURITY_ENCRYPTION_TRANSPORT)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT; return 0;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_TRANSPORT */
+#ifdef SO_SELECT_ERR_QUEUE
+       if (x == SO_SELECT_ERR_QUEUE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE; return 0;}
+#endif /* ndef SO_SELECT_ERR_QUEUE */
+#ifdef SO_SNDBUF
+       if (x == SO_SNDBUF)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SNDBUF; return 0;}
+#endif /* ndef SO_SNDBUF */
+#ifdef SO_SNDBUFFORCE
+       if (x == SO_SNDBUFFORCE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE; return 0;}
+#endif /* ndef SO_SNDBUFFORCE */
+#ifdef SO_SNDLOWAT
+       if (x == SO_SNDLOWAT)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT; return 0;}
+#endif /* ndef SO_SNDLOWAT */
+#ifdef SO_SNDTIMEO
+       if (x == SO_SNDTIMEO)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO; return 0;}
+#endif /* ndef SO_SNDTIMEO */
+#ifdef SO_TIMESTAMP
+       if (x == SO_TIMESTAMP)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP; return 0;}
+#endif /* ndef SO_TIMESTAMP */
+#ifdef SO_TIMESTAMPING
+       if (x == SO_TIMESTAMPING)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING; return 0;}
+#endif /* ndef SO_TIMESTAMPING */
+#ifdef SO_TIMESTAMPNS
+       if (x == SO_TIMESTAMPNS)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS; return 0;}
+#endif /* ndef SO_TIMESTAMPNS */
+#ifdef SO_TYPE
+       if (x == SO_TYPE)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_TYPE; return 0;}
+#endif /* ndef SO_TYPE */
+#ifdef SO_WIFI_STATUS
+       if (x == SO_WIFI_STATUS)
+               {*r = Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS; return 0;}
+#endif /* ndef SO_WIFI_STATUS */
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_FromUnixSocketProtocol (int x, int *r)
+{
+       *r = 0;
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_AH)
+#ifdef IPPROTO_AH
+               {*r = IPPROTO_AH; return 0;}
+#else /* def IPPROTO_AH */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_AH */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH)
+#ifdef IPPROTO_BEETPH
+               {*r = IPPROTO_BEETPH; return 0;}
+#else /* def IPPROTO_BEETPH */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_BEETPH */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_COMP)
+#ifdef IPPROTO_COMP
+               {*r = IPPROTO_COMP; return 0;}
+#else /* def IPPROTO_COMP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_COMP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP)
+#ifdef IPPROTO_DCCP
+               {*r = IPPROTO_DCCP; return 0;}
+#else /* def IPPROTO_DCCP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_DCCP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_EGP)
+#ifdef IPPROTO_EGP
+               {*r = IPPROTO_EGP; return 0;}
+#else /* def IPPROTO_EGP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_EGP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP)
+#ifdef IPPROTO_ENCAP
+               {*r = IPPROTO_ENCAP; return 0;}
+#else /* def IPPROTO_ENCAP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_ENCAP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_ESP)
+#ifdef IPPROTO_ESP
+               {*r = IPPROTO_ESP; return 0;}
+#else /* def IPPROTO_ESP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_ESP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_GRE)
+#ifdef IPPROTO_GRE
+               {*r = IPPROTO_GRE; return 0;}
+#else /* def IPPROTO_GRE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_GRE */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP)
+#ifdef IPPROTO_ICMP
+               {*r = IPPROTO_ICMP; return 0;}
+#else /* def IPPROTO_ICMP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_ICMP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IDP)
+#ifdef IPPROTO_IDP
+               {*r = IPPROTO_IDP; return 0;}
+#else /* def IPPROTO_IDP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IDP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP)
+#ifdef IPPROTO_IGMP
+               {*r = IPPROTO_IGMP; return 0;}
+#else /* def IPPROTO_IGMP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IGMP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IP)
+#ifdef IPPROTO_IP
+               {*r = IPPROTO_IP; return 0;}
+#else /* def IPPROTO_IP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP)
+#ifdef IPPROTO_IPIP
+               {*r = IPPROTO_IPIP; return 0;}
+#else /* def IPPROTO_IPIP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IPIP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6)
+#ifdef IPPROTO_IPV6
+               {*r = IPPROTO_IPV6; return 0;}
+#else /* def IPPROTO_IPV6 */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IPV6 */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_MTP)
+#ifdef IPPROTO_MTP
+               {*r = IPPROTO_MTP; return 0;}
+#else /* def IPPROTO_MTP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_MTP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_PIM)
+#ifdef IPPROTO_PIM
+               {*r = IPPROTO_PIM; return 0;}
+#else /* def IPPROTO_PIM */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_PIM */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_PUP)
+#ifdef IPPROTO_PUP
+               {*r = IPPROTO_PUP; return 0;}
+#else /* def IPPROTO_PUP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_PUP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_RAW)
+#ifdef IPPROTO_RAW
+               {*r = IPPROTO_RAW; return 0;}
+#else /* def IPPROTO_RAW */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_RAW */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP)
+#ifdef IPPROTO_RSVP
+               {*r = IPPROTO_RSVP; return 0;}
+#else /* def IPPROTO_RSVP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_RSVP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP)
+#ifdef IPPROTO_SCTP
+               {*r = IPPROTO_SCTP; return 0;}
+#else /* def IPPROTO_SCTP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_SCTP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_TCP)
+#ifdef IPPROTO_TCP
+               {*r = IPPROTO_TCP; return 0;}
+#else /* def IPPROTO_TCP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_TCP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_TP)
+#ifdef IPPROTO_TP
+               {*r = IPPROTO_TP; return 0;}
+#else /* def IPPROTO_TP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_TP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_UDP)
+#ifdef IPPROTO_UDP
+               {*r = IPPROTO_UDP; return 0;}
+#else /* def IPPROTO_UDP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_UDP */
+       if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE)
+#ifdef IPPROTO_UDPLITE
+               {*r = IPPROTO_UDPLITE; return 0;}
+#else /* def IPPROTO_UDPLITE */
+               {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_UDPLITE */
+       if (x == Mono_Posix_UnixSocketProtocol_SOL_SOCKET)
+#ifdef SOL_SOCKET
+               {*r = SOL_SOCKET; return 0;}
+#else /* def SOL_SOCKET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOL_SOCKET */
+       if (x == 0)
+               return 0;
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixSocketProtocol (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef IPPROTO_AH
+       if (x == IPPROTO_AH)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_AH; return 0;}
+#endif /* ndef IPPROTO_AH */
+#ifdef IPPROTO_BEETPH
+       if (x == IPPROTO_BEETPH)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH; return 0;}
+#endif /* ndef IPPROTO_BEETPH */
+#ifdef IPPROTO_COMP
+       if (x == IPPROTO_COMP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_COMP; return 0;}
+#endif /* ndef IPPROTO_COMP */
+#ifdef IPPROTO_DCCP
+       if (x == IPPROTO_DCCP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP; return 0;}
+#endif /* ndef IPPROTO_DCCP */
+#ifdef IPPROTO_EGP
+       if (x == IPPROTO_EGP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_EGP; return 0;}
+#endif /* ndef IPPROTO_EGP */
+#ifdef IPPROTO_ENCAP
+       if (x == IPPROTO_ENCAP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP; return 0;}
+#endif /* ndef IPPROTO_ENCAP */
+#ifdef IPPROTO_ESP
+       if (x == IPPROTO_ESP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_ESP; return 0;}
+#endif /* ndef IPPROTO_ESP */
+#ifdef IPPROTO_GRE
+       if (x == IPPROTO_GRE)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_GRE; return 0;}
+#endif /* ndef IPPROTO_GRE */
+#ifdef IPPROTO_ICMP
+       if (x == IPPROTO_ICMP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP; return 0;}
+#endif /* ndef IPPROTO_ICMP */
+#ifdef IPPROTO_IDP
+       if (x == IPPROTO_IDP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IDP; return 0;}
+#endif /* ndef IPPROTO_IDP */
+#ifdef IPPROTO_IGMP
+       if (x == IPPROTO_IGMP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP; return 0;}
+#endif /* ndef IPPROTO_IGMP */
+#ifdef IPPROTO_IP
+       if (x == IPPROTO_IP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IP; return 0;}
+#endif /* ndef IPPROTO_IP */
+#ifdef IPPROTO_IPIP
+       if (x == IPPROTO_IPIP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP; return 0;}
+#endif /* ndef IPPROTO_IPIP */
+#ifdef IPPROTO_IPV6
+       if (x == IPPROTO_IPV6)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6; return 0;}
+#endif /* ndef IPPROTO_IPV6 */
+#ifdef IPPROTO_MTP
+       if (x == IPPROTO_MTP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_MTP; return 0;}
+#endif /* ndef IPPROTO_MTP */
+#ifdef IPPROTO_PIM
+       if (x == IPPROTO_PIM)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_PIM; return 0;}
+#endif /* ndef IPPROTO_PIM */
+#ifdef IPPROTO_PUP
+       if (x == IPPROTO_PUP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_PUP; return 0;}
+#endif /* ndef IPPROTO_PUP */
+#ifdef IPPROTO_RAW
+       if (x == IPPROTO_RAW)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_RAW; return 0;}
+#endif /* ndef IPPROTO_RAW */
+#ifdef IPPROTO_RSVP
+       if (x == IPPROTO_RSVP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP; return 0;}
+#endif /* ndef IPPROTO_RSVP */
+#ifdef IPPROTO_SCTP
+       if (x == IPPROTO_SCTP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP; return 0;}
+#endif /* ndef IPPROTO_SCTP */
+#ifdef IPPROTO_TCP
+       if (x == IPPROTO_TCP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_TCP; return 0;}
+#endif /* ndef IPPROTO_TCP */
+#ifdef IPPROTO_TP
+       if (x == IPPROTO_TP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_TP; return 0;}
+#endif /* ndef IPPROTO_TP */
+#ifdef IPPROTO_UDP
+       if (x == IPPROTO_UDP)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_UDP; return 0;}
+#endif /* ndef IPPROTO_UDP */
+#ifdef IPPROTO_UDPLITE
+       if (x == IPPROTO_UDPLITE)
+               {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE; return 0;}
+#endif /* ndef IPPROTO_UDPLITE */
+#ifdef SOL_SOCKET
+       if (x == SOL_SOCKET)
+               {*r = Mono_Posix_UnixSocketProtocol_SOL_SOCKET; return 0;}
+#endif /* ndef SOL_SOCKET */
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_FromUnixSocketType (int x, int *r)
+{
+       *r = 0;
+       if (x == Mono_Posix_UnixSocketType_SOCK_DCCP)
+#ifdef SOCK_DCCP
+               {*r = SOCK_DCCP; return 0;}
+#else /* def SOCK_DCCP */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_DCCP */
+       if (x == Mono_Posix_UnixSocketType_SOCK_DGRAM)
+#ifdef SOCK_DGRAM
+               {*r = SOCK_DGRAM; return 0;}
+#else /* def SOCK_DGRAM */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_DGRAM */
+       if (x == Mono_Posix_UnixSocketType_SOCK_PACKET)
+#ifdef SOCK_PACKET
+               {*r = SOCK_PACKET; return 0;}
+#else /* def SOCK_PACKET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_PACKET */
+       if (x == Mono_Posix_UnixSocketType_SOCK_RAW)
+#ifdef SOCK_RAW
+               {*r = SOCK_RAW; return 0;}
+#else /* def SOCK_RAW */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_RAW */
+       if (x == Mono_Posix_UnixSocketType_SOCK_RDM)
+#ifdef SOCK_RDM
+               {*r = SOCK_RDM; return 0;}
+#else /* def SOCK_RDM */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_RDM */
+       if (x == Mono_Posix_UnixSocketType_SOCK_SEQPACKET)
+#ifdef SOCK_SEQPACKET
+               {*r = SOCK_SEQPACKET; return 0;}
+#else /* def SOCK_SEQPACKET */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_SEQPACKET */
+       if (x == Mono_Posix_UnixSocketType_SOCK_STREAM)
+#ifdef SOCK_STREAM
+               {*r = SOCK_STREAM; return 0;}
+#else /* def SOCK_STREAM */
+               {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_STREAM */
+       if (x == 0)
+               return 0;
+       errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixSocketType (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef SOCK_DCCP
+       if (x == SOCK_DCCP)
+               {*r = Mono_Posix_UnixSocketType_SOCK_DCCP; return 0;}
+#endif /* ndef SOCK_DCCP */
+#ifdef SOCK_DGRAM
+       if (x == SOCK_DGRAM)
+               {*r = Mono_Posix_UnixSocketType_SOCK_DGRAM; return 0;}
+#endif /* ndef SOCK_DGRAM */
+#ifdef SOCK_PACKET
+       if (x == SOCK_PACKET)
+               {*r = Mono_Posix_UnixSocketType_SOCK_PACKET; return 0;}
+#endif /* ndef SOCK_PACKET */
+#ifdef SOCK_RAW
+       if (x == SOCK_RAW)
+               {*r = Mono_Posix_UnixSocketType_SOCK_RAW; return 0;}
+#endif /* ndef SOCK_RAW */
+#ifdef SOCK_RDM
+       if (x == SOCK_RDM)
+               {*r = Mono_Posix_UnixSocketType_SOCK_RDM; return 0;}
+#endif /* ndef SOCK_RDM */
+#ifdef SOCK_SEQPACKET
+       if (x == SOCK_SEQPACKET)
+               {*r = Mono_Posix_UnixSocketType_SOCK_SEQPACKET; return 0;}
+#endif /* ndef SOCK_SEQPACKET */
+#ifdef SOCK_STREAM
+       if (x == SOCK_STREAM)
+               {*r = Mono_Posix_UnixSocketType_SOCK_STREAM; return 0;}
+#endif /* ndef SOCK_STREAM */
+       errno = EINVAL; return -1;
+}
+
 #ifdef HAVE_STRUCT_UTIMBUF
 int
 Mono_Posix_FromUtimbuf (struct Mono_Posix_Utimbuf *from, struct utimbuf *to)
index 9c170eac0dc5faf2d525c4e40aa2121080901830..34cdb68ab4da8bab5ff81cddbf5c53e4e976b712 100644 (file)
@@ -621,6 +621,49 @@ enum Mono_Posix_LockfCommand {
 int Mono_Posix_FromLockfCommand (int x, int *r);
 int Mono_Posix_ToLockfCommand (int x, int *r);
 
+enum Mono_Posix_MessageFlags {
+       Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC       = 0x40000000,
+       #define Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC
+       Mono_Posix_MessageFlags_MSG_CONFIRM            = 0x00000800,
+       #define Mono_Posix_MessageFlags_MSG_CONFIRM      Mono_Posix_MessageFlags_MSG_CONFIRM
+       Mono_Posix_MessageFlags_MSG_CTRUNC             = 0x00000008,
+       #define Mono_Posix_MessageFlags_MSG_CTRUNC       Mono_Posix_MessageFlags_MSG_CTRUNC
+       Mono_Posix_MessageFlags_MSG_DONTROUTE          = 0x00000004,
+       #define Mono_Posix_MessageFlags_MSG_DONTROUTE    Mono_Posix_MessageFlags_MSG_DONTROUTE
+       Mono_Posix_MessageFlags_MSG_DONTWAIT           = 0x00000040,
+       #define Mono_Posix_MessageFlags_MSG_DONTWAIT     Mono_Posix_MessageFlags_MSG_DONTWAIT
+       Mono_Posix_MessageFlags_MSG_EOR                = 0x00000080,
+       #define Mono_Posix_MessageFlags_MSG_EOR          Mono_Posix_MessageFlags_MSG_EOR
+       Mono_Posix_MessageFlags_MSG_ERRQUEUE           = 0x00002000,
+       #define Mono_Posix_MessageFlags_MSG_ERRQUEUE     Mono_Posix_MessageFlags_MSG_ERRQUEUE
+       Mono_Posix_MessageFlags_MSG_FASTOPEN           = 0x20000000,
+       #define Mono_Posix_MessageFlags_MSG_FASTOPEN     Mono_Posix_MessageFlags_MSG_FASTOPEN
+       Mono_Posix_MessageFlags_MSG_FIN                = 0x00000200,
+       #define Mono_Posix_MessageFlags_MSG_FIN          Mono_Posix_MessageFlags_MSG_FIN
+       Mono_Posix_MessageFlags_MSG_MORE               = 0x00008000,
+       #define Mono_Posix_MessageFlags_MSG_MORE         Mono_Posix_MessageFlags_MSG_MORE
+       Mono_Posix_MessageFlags_MSG_NOSIGNAL           = 0x00004000,
+       #define Mono_Posix_MessageFlags_MSG_NOSIGNAL     Mono_Posix_MessageFlags_MSG_NOSIGNAL
+       Mono_Posix_MessageFlags_MSG_OOB                = 0x00000001,
+       #define Mono_Posix_MessageFlags_MSG_OOB          Mono_Posix_MessageFlags_MSG_OOB
+       Mono_Posix_MessageFlags_MSG_PEEK               = 0x00000002,
+       #define Mono_Posix_MessageFlags_MSG_PEEK         Mono_Posix_MessageFlags_MSG_PEEK
+       Mono_Posix_MessageFlags_MSG_PROXY              = 0x00000010,
+       #define Mono_Posix_MessageFlags_MSG_PROXY        Mono_Posix_MessageFlags_MSG_PROXY
+       Mono_Posix_MessageFlags_MSG_RST                = 0x00001000,
+       #define Mono_Posix_MessageFlags_MSG_RST          Mono_Posix_MessageFlags_MSG_RST
+       Mono_Posix_MessageFlags_MSG_SYN                = 0x00000400,
+       #define Mono_Posix_MessageFlags_MSG_SYN          Mono_Posix_MessageFlags_MSG_SYN
+       Mono_Posix_MessageFlags_MSG_TRUNC              = 0x00000020,
+       #define Mono_Posix_MessageFlags_MSG_TRUNC        Mono_Posix_MessageFlags_MSG_TRUNC
+       Mono_Posix_MessageFlags_MSG_WAITALL            = 0x00000100,
+       #define Mono_Posix_MessageFlags_MSG_WAITALL      Mono_Posix_MessageFlags_MSG_WAITALL
+       Mono_Posix_MessageFlags_MSG_WAITFORONE         = 0x00010000,
+       #define Mono_Posix_MessageFlags_MSG_WAITFORONE   Mono_Posix_MessageFlags_MSG_WAITFORONE
+};
+int Mono_Posix_FromMessageFlags (int x, int *r);
+int Mono_Posix_ToMessageFlags (int x, int *r);
+
 enum Mono_Posix_MlockallFlags {
        Mono_Posix_MlockallFlags_MCL_CURRENT       = 0x00000001,
        #define Mono_Posix_MlockallFlags_MCL_CURRENT Mono_Posix_MlockallFlags_MCL_CURRENT
@@ -889,6 +932,17 @@ enum Mono_Posix_SeekFlags {
 int Mono_Posix_FromSeekFlags (short x, short *r);
 int Mono_Posix_ToSeekFlags (short x, short *r);
 
+enum Mono_Posix_ShutdownOption {
+       Mono_Posix_ShutdownOption_SHUT_RD         = 0x00000001,
+       #define Mono_Posix_ShutdownOption_SHUT_RD   Mono_Posix_ShutdownOption_SHUT_RD
+       Mono_Posix_ShutdownOption_SHUT_RDWR       = 0x00000003,
+       #define Mono_Posix_ShutdownOption_SHUT_RDWR Mono_Posix_ShutdownOption_SHUT_RDWR
+       Mono_Posix_ShutdownOption_SHUT_WR         = 0x00000002,
+       #define Mono_Posix_ShutdownOption_SHUT_WR   Mono_Posix_ShutdownOption_SHUT_WR
+};
+int Mono_Posix_FromShutdownOption (int x, int *r);
+int Mono_Posix_ToShutdownOption (int x, int *r);
+
 enum Mono_Posix_Signum {
        Mono_Posix_Signum_SIGABRT         = 0x00000006,
        #define Mono_Posix_Signum_SIGABRT   Mono_Posix_Signum_SIGABRT
@@ -1454,6 +1508,271 @@ enum Mono_Posix_SyslogOptions {
 int Mono_Posix_FromSyslogOptions (int x, int *r);
 int Mono_Posix_ToSyslogOptions (int x, int *r);
 
+enum Mono_Posix_UnixAddressFamily {
+       Mono_Posix_UnixAddressFamily_AF_ALG              = 0x00000026,
+       #define Mono_Posix_UnixAddressFamily_AF_ALG        Mono_Posix_UnixAddressFamily_AF_ALG
+       Mono_Posix_UnixAddressFamily_AF_APPLETALK        = 0x00000005,
+       #define Mono_Posix_UnixAddressFamily_AF_APPLETALK  Mono_Posix_UnixAddressFamily_AF_APPLETALK
+       Mono_Posix_UnixAddressFamily_AF_ASH              = 0x00000012,
+       #define Mono_Posix_UnixAddressFamily_AF_ASH        Mono_Posix_UnixAddressFamily_AF_ASH
+       Mono_Posix_UnixAddressFamily_AF_ATMPVC           = 0x00000008,
+       #define Mono_Posix_UnixAddressFamily_AF_ATMPVC     Mono_Posix_UnixAddressFamily_AF_ATMPVC
+       Mono_Posix_UnixAddressFamily_AF_ATMSVC           = 0x00000014,
+       #define Mono_Posix_UnixAddressFamily_AF_ATMSVC     Mono_Posix_UnixAddressFamily_AF_ATMSVC
+       Mono_Posix_UnixAddressFamily_AF_AX25             = 0x00000003,
+       #define Mono_Posix_UnixAddressFamily_AF_AX25       Mono_Posix_UnixAddressFamily_AF_AX25
+       Mono_Posix_UnixAddressFamily_AF_BLUETOOTH        = 0x0000001f,
+       #define Mono_Posix_UnixAddressFamily_AF_BLUETOOTH  Mono_Posix_UnixAddressFamily_AF_BLUETOOTH
+       Mono_Posix_UnixAddressFamily_AF_BRIDGE           = 0x00000007,
+       #define Mono_Posix_UnixAddressFamily_AF_BRIDGE     Mono_Posix_UnixAddressFamily_AF_BRIDGE
+       Mono_Posix_UnixAddressFamily_AF_CAIF             = 0x00000025,
+       #define Mono_Posix_UnixAddressFamily_AF_CAIF       Mono_Posix_UnixAddressFamily_AF_CAIF
+       Mono_Posix_UnixAddressFamily_AF_CAN              = 0x0000001d,
+       #define Mono_Posix_UnixAddressFamily_AF_CAN        Mono_Posix_UnixAddressFamily_AF_CAN
+       Mono_Posix_UnixAddressFamily_AF_DECnet           = 0x0000000c,
+       #define Mono_Posix_UnixAddressFamily_AF_DECnet     Mono_Posix_UnixAddressFamily_AF_DECnet
+       Mono_Posix_UnixAddressFamily_AF_ECONET           = 0x00000013,
+       #define Mono_Posix_UnixAddressFamily_AF_ECONET     Mono_Posix_UnixAddressFamily_AF_ECONET
+       Mono_Posix_UnixAddressFamily_AF_IEEE802154       = 0x00000024,
+       #define Mono_Posix_UnixAddressFamily_AF_IEEE802154 Mono_Posix_UnixAddressFamily_AF_IEEE802154
+       Mono_Posix_UnixAddressFamily_AF_INET             = 0x00000002,
+       #define Mono_Posix_UnixAddressFamily_AF_INET       Mono_Posix_UnixAddressFamily_AF_INET
+       Mono_Posix_UnixAddressFamily_AF_INET6            = 0x0000000a,
+       #define Mono_Posix_UnixAddressFamily_AF_INET6      Mono_Posix_UnixAddressFamily_AF_INET6
+       Mono_Posix_UnixAddressFamily_AF_IPX              = 0x00000004,
+       #define Mono_Posix_UnixAddressFamily_AF_IPX        Mono_Posix_UnixAddressFamily_AF_IPX
+       Mono_Posix_UnixAddressFamily_AF_IRDA             = 0x00000017,
+       #define Mono_Posix_UnixAddressFamily_AF_IRDA       Mono_Posix_UnixAddressFamily_AF_IRDA
+       Mono_Posix_UnixAddressFamily_AF_ISDN             = 0x00000022,
+       #define Mono_Posix_UnixAddressFamily_AF_ISDN       Mono_Posix_UnixAddressFamily_AF_ISDN
+       Mono_Posix_UnixAddressFamily_AF_IUCV             = 0x00000020,
+       #define Mono_Posix_UnixAddressFamily_AF_IUCV       Mono_Posix_UnixAddressFamily_AF_IUCV
+       Mono_Posix_UnixAddressFamily_AF_KEY              = 0x0000000f,
+       #define Mono_Posix_UnixAddressFamily_AF_KEY        Mono_Posix_UnixAddressFamily_AF_KEY
+       Mono_Posix_UnixAddressFamily_AF_LLC              = 0x0000001a,
+       #define Mono_Posix_UnixAddressFamily_AF_LLC        Mono_Posix_UnixAddressFamily_AF_LLC
+       Mono_Posix_UnixAddressFamily_AF_NETBEUI          = 0x0000000d,
+       #define Mono_Posix_UnixAddressFamily_AF_NETBEUI    Mono_Posix_UnixAddressFamily_AF_NETBEUI
+       Mono_Posix_UnixAddressFamily_AF_NETLINK          = 0x00000010,
+       #define Mono_Posix_UnixAddressFamily_AF_NETLINK    Mono_Posix_UnixAddressFamily_AF_NETLINK
+       Mono_Posix_UnixAddressFamily_AF_NETROM           = 0x00000006,
+       #define Mono_Posix_UnixAddressFamily_AF_NETROM     Mono_Posix_UnixAddressFamily_AF_NETROM
+       Mono_Posix_UnixAddressFamily_AF_NFC              = 0x00000027,
+       #define Mono_Posix_UnixAddressFamily_AF_NFC        Mono_Posix_UnixAddressFamily_AF_NFC
+       Mono_Posix_UnixAddressFamily_AF_PACKET           = 0x00000011,
+       #define Mono_Posix_UnixAddressFamily_AF_PACKET     Mono_Posix_UnixAddressFamily_AF_PACKET
+       Mono_Posix_UnixAddressFamily_AF_PHONET           = 0x00000023,
+       #define Mono_Posix_UnixAddressFamily_AF_PHONET     Mono_Posix_UnixAddressFamily_AF_PHONET
+       Mono_Posix_UnixAddressFamily_AF_PPPOX            = 0x00000018,
+       #define Mono_Posix_UnixAddressFamily_AF_PPPOX      Mono_Posix_UnixAddressFamily_AF_PPPOX
+       Mono_Posix_UnixAddressFamily_AF_RDS              = 0x00000015,
+       #define Mono_Posix_UnixAddressFamily_AF_RDS        Mono_Posix_UnixAddressFamily_AF_RDS
+       Mono_Posix_UnixAddressFamily_AF_ROSE             = 0x0000000b,
+       #define Mono_Posix_UnixAddressFamily_AF_ROSE       Mono_Posix_UnixAddressFamily_AF_ROSE
+       Mono_Posix_UnixAddressFamily_AF_RXRPC            = 0x00000021,
+       #define Mono_Posix_UnixAddressFamily_AF_RXRPC      Mono_Posix_UnixAddressFamily_AF_RXRPC
+       Mono_Posix_UnixAddressFamily_AF_SECURITY         = 0x0000000e,
+       #define Mono_Posix_UnixAddressFamily_AF_SECURITY   Mono_Posix_UnixAddressFamily_AF_SECURITY
+       Mono_Posix_UnixAddressFamily_AF_SNA              = 0x00000016,
+       #define Mono_Posix_UnixAddressFamily_AF_SNA        Mono_Posix_UnixAddressFamily_AF_SNA
+       Mono_Posix_UnixAddressFamily_AF_TIPC             = 0x0000001e,
+       #define Mono_Posix_UnixAddressFamily_AF_TIPC       Mono_Posix_UnixAddressFamily_AF_TIPC
+       Mono_Posix_UnixAddressFamily_AF_UNIX             = 0x00000001,
+       #define Mono_Posix_UnixAddressFamily_AF_UNIX       Mono_Posix_UnixAddressFamily_AF_UNIX
+       Mono_Posix_UnixAddressFamily_AF_UNSPEC           = 0x00000000,
+       #define Mono_Posix_UnixAddressFamily_AF_UNSPEC     Mono_Posix_UnixAddressFamily_AF_UNSPEC
+       Mono_Posix_UnixAddressFamily_AF_VSOCK            = 0x00000028,
+       #define Mono_Posix_UnixAddressFamily_AF_VSOCK      Mono_Posix_UnixAddressFamily_AF_VSOCK
+       Mono_Posix_UnixAddressFamily_AF_WANPIPE          = 0x00000019,
+       #define Mono_Posix_UnixAddressFamily_AF_WANPIPE    Mono_Posix_UnixAddressFamily_AF_WANPIPE
+       Mono_Posix_UnixAddressFamily_AF_X25              = 0x00000009,
+       #define Mono_Posix_UnixAddressFamily_AF_X25        Mono_Posix_UnixAddressFamily_AF_X25
+};
+int Mono_Posix_FromUnixAddressFamily (int x, int *r);
+int Mono_Posix_ToUnixAddressFamily (int x, int *r);
+
+enum Mono_Posix_UnixSocketFlags {
+       Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC        = 0x00080000,
+       #define Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC  Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC
+       Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK       = 0x00000800,
+       #define Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK
+};
+int Mono_Posix_FromUnixSocketFlags (int x, int *r);
+int Mono_Posix_ToUnixSocketFlags (int x, int *r);
+
+enum Mono_Posix_UnixSocketOptionName {
+       Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN                          = 0x0000001e,
+       #define Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN                    Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN
+       Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER                       = 0x0000001a,
+       #define Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER                 Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER
+       Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE                        = 0x00000019,
+       #define Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE                  Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE
+       Mono_Posix_UnixSocketOptionName_SO_BROADCAST                           = 0x00000006,
+       #define Mono_Posix_UnixSocketOptionName_SO_BROADCAST                     Mono_Posix_UnixSocketOptionName_SO_BROADCAST
+       Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT                           = 0x0000000e,
+       #define Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT                     Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT
+       Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL                           = 0x0000002e,
+       #define Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL                     Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL
+       Mono_Posix_UnixSocketOptionName_SO_DEBUG                               = 0x00000001,
+       #define Mono_Posix_UnixSocketOptionName_SO_DEBUG                         Mono_Posix_UnixSocketOptionName_SO_DEBUG
+       Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER                       = 0x0000001b,
+       #define Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER                 Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER
+       Mono_Posix_UnixSocketOptionName_SO_DOMAIN                              = 0x00000027,
+       #define Mono_Posix_UnixSocketOptionName_SO_DOMAIN                        Mono_Posix_UnixSocketOptionName_SO_DOMAIN
+       Mono_Posix_UnixSocketOptionName_SO_DONTROUTE                           = 0x00000005,
+       #define Mono_Posix_UnixSocketOptionName_SO_DONTROUTE                     Mono_Posix_UnixSocketOptionName_SO_DONTROUTE
+       Mono_Posix_UnixSocketOptionName_SO_ERROR                               = 0x00000004,
+       #define Mono_Posix_UnixSocketOptionName_SO_ERROR                         Mono_Posix_UnixSocketOptionName_SO_ERROR
+       Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE                           = 0x00000009,
+       #define Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE                     Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE
+       Mono_Posix_UnixSocketOptionName_SO_LINGER                              = 0x0000000d,
+       #define Mono_Posix_UnixSocketOptionName_SO_LINGER                        Mono_Posix_UnixSocketOptionName_SO_LINGER
+       Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER                         = 0x0000002c,
+       #define Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER                   Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER
+       Mono_Posix_UnixSocketOptionName_SO_MARK                                = 0x00000024,
+       #define Mono_Posix_UnixSocketOptionName_SO_MARK                          Mono_Posix_UnixSocketOptionName_SO_MARK
+       Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE                     = 0x0000002f,
+       #define Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE               Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE
+       Mono_Posix_UnixSocketOptionName_SO_NOFCS                               = 0x0000002b,
+       #define Mono_Posix_UnixSocketOptionName_SO_NOFCS                         Mono_Posix_UnixSocketOptionName_SO_NOFCS
+       Mono_Posix_UnixSocketOptionName_SO_NO_CHECK                            = 0x0000000b,
+       #define Mono_Posix_UnixSocketOptionName_SO_NO_CHECK                      Mono_Posix_UnixSocketOptionName_SO_NO_CHECK
+       Mono_Posix_UnixSocketOptionName_SO_OOBINLINE                           = 0x0000000a,
+       #define Mono_Posix_UnixSocketOptionName_SO_OOBINLINE                     Mono_Posix_UnixSocketOptionName_SO_OOBINLINE
+       Mono_Posix_UnixSocketOptionName_SO_PASSCRED                            = 0x00000010,
+       #define Mono_Posix_UnixSocketOptionName_SO_PASSCRED                      Mono_Posix_UnixSocketOptionName_SO_PASSCRED
+       Mono_Posix_UnixSocketOptionName_SO_PASSSEC                             = 0x00000022,
+       #define Mono_Posix_UnixSocketOptionName_SO_PASSSEC                       Mono_Posix_UnixSocketOptionName_SO_PASSSEC
+       Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF                            = 0x0000002a,
+       #define Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF                      Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF
+       Mono_Posix_UnixSocketOptionName_SO_PEERCRED                            = 0x00000011,
+       #define Mono_Posix_UnixSocketOptionName_SO_PEERCRED                      Mono_Posix_UnixSocketOptionName_SO_PEERCRED
+       Mono_Posix_UnixSocketOptionName_SO_PEERNAME                            = 0x0000001c,
+       #define Mono_Posix_UnixSocketOptionName_SO_PEERNAME                      Mono_Posix_UnixSocketOptionName_SO_PEERNAME
+       Mono_Posix_UnixSocketOptionName_SO_PEERSEC                             = 0x0000001f,
+       #define Mono_Posix_UnixSocketOptionName_SO_PEERSEC                       Mono_Posix_UnixSocketOptionName_SO_PEERSEC
+       Mono_Posix_UnixSocketOptionName_SO_PRIORITY                            = 0x0000000c,
+       #define Mono_Posix_UnixSocketOptionName_SO_PRIORITY                      Mono_Posix_UnixSocketOptionName_SO_PRIORITY
+       Mono_Posix_UnixSocketOptionName_SO_PROTOCOL                            = 0x00000026,
+       #define Mono_Posix_UnixSocketOptionName_SO_PROTOCOL                      Mono_Posix_UnixSocketOptionName_SO_PROTOCOL
+       Mono_Posix_UnixSocketOptionName_SO_RCVBUF                              = 0x00000008,
+       #define Mono_Posix_UnixSocketOptionName_SO_RCVBUF                        Mono_Posix_UnixSocketOptionName_SO_RCVBUF
+       Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE                         = 0x00000021,
+       #define Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE                   Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE
+       Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT                            = 0x00000012,
+       #define Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT                      Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT
+       Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO                            = 0x00000014,
+       #define Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO                      Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO
+       Mono_Posix_UnixSocketOptionName_SO_REUSEADDR                           = 0x00000002,
+       #define Mono_Posix_UnixSocketOptionName_SO_REUSEADDR                     Mono_Posix_UnixSocketOptionName_SO_REUSEADDR
+       Mono_Posix_UnixSocketOptionName_SO_REUSEPORT                           = 0x0000000f,
+       #define Mono_Posix_UnixSocketOptionName_SO_REUSEPORT                     Mono_Posix_UnixSocketOptionName_SO_REUSEPORT
+       Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL                            = 0x00000028,
+       #define Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL                      Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL
+       Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION             = 0x00000016,
+       #define Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION       Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION
+       Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK         = 0x00000018,
+       #define Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK   Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK
+       Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT       = 0x00000017,
+       #define Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT
+       Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE                    = 0x0000002d,
+       #define Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE              Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE
+       Mono_Posix_UnixSocketOptionName_SO_SNDBUF                              = 0x00000007,
+       #define Mono_Posix_UnixSocketOptionName_SO_SNDBUF                        Mono_Posix_UnixSocketOptionName_SO_SNDBUF
+       Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE                         = 0x00000020,
+       #define Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE                   Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE
+       Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT                            = 0x00000013,
+       #define Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT                      Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT
+       Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO                            = 0x00000015,
+       #define Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO                      Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO
+       Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP                           = 0x0000001d,
+       #define Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP                     Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP
+       Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING                        = 0x00000025,
+       #define Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING                  Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING
+       Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS                         = 0x00000023,
+       #define Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS                   Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS
+       Mono_Posix_UnixSocketOptionName_SO_TYPE                                = 0x00000003,
+       #define Mono_Posix_UnixSocketOptionName_SO_TYPE                          Mono_Posix_UnixSocketOptionName_SO_TYPE
+       Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS                         = 0x00000029,
+       #define Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS                   Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS
+};
+int Mono_Posix_FromUnixSocketOptionName (int x, int *r);
+int Mono_Posix_ToUnixSocketOptionName (int x, int *r);
+
+enum Mono_Posix_UnixSocketProtocol {
+       Mono_Posix_UnixSocketProtocol_IPPROTO_AH            = 0x00000033,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_AH      Mono_Posix_UnixSocketProtocol_IPPROTO_AH
+       Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH        = 0x0000005e,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH  Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH
+       Mono_Posix_UnixSocketProtocol_IPPROTO_COMP          = 0x0000006c,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_COMP    Mono_Posix_UnixSocketProtocol_IPPROTO_COMP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP          = 0x00000021,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP    Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_EGP           = 0x00000008,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_EGP     Mono_Posix_UnixSocketProtocol_IPPROTO_EGP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP         = 0x00000062,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP   Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_ESP           = 0x00000032,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_ESP     Mono_Posix_UnixSocketProtocol_IPPROTO_ESP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_GRE           = 0x0000002f,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_GRE     Mono_Posix_UnixSocketProtocol_IPPROTO_GRE
+       Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP          = 0x00000001,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP    Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_IDP           = 0x00000016,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_IDP     Mono_Posix_UnixSocketProtocol_IPPROTO_IDP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP          = 0x00000002,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP    Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_IP            = 0x00000400,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_IP      Mono_Posix_UnixSocketProtocol_IPPROTO_IP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP          = 0x00000004,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP    Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6          = 0x00000029,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6    Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6
+       Mono_Posix_UnixSocketProtocol_IPPROTO_MTP           = 0x0000005c,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_MTP     Mono_Posix_UnixSocketProtocol_IPPROTO_MTP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_PIM           = 0x00000067,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_PIM     Mono_Posix_UnixSocketProtocol_IPPROTO_PIM
+       Mono_Posix_UnixSocketProtocol_IPPROTO_PUP           = 0x0000000c,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_PUP     Mono_Posix_UnixSocketProtocol_IPPROTO_PUP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_RAW           = 0x000000ff,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_RAW     Mono_Posix_UnixSocketProtocol_IPPROTO_RAW
+       Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP          = 0x0000002e,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP    Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP          = 0x00000084,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP    Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_TCP           = 0x00000006,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_TCP     Mono_Posix_UnixSocketProtocol_IPPROTO_TCP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_TP            = 0x0000001d,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_TP      Mono_Posix_UnixSocketProtocol_IPPROTO_TP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_UDP           = 0x00000011,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_UDP     Mono_Posix_UnixSocketProtocol_IPPROTO_UDP
+       Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE       = 0x00000088,
+       #define Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE
+       Mono_Posix_UnixSocketProtocol_SOL_SOCKET            = 0x00000800,
+       #define Mono_Posix_UnixSocketProtocol_SOL_SOCKET      Mono_Posix_UnixSocketProtocol_SOL_SOCKET
+};
+int Mono_Posix_FromUnixSocketProtocol (int x, int *r);
+int Mono_Posix_ToUnixSocketProtocol (int x, int *r);
+
+enum Mono_Posix_UnixSocketType {
+       Mono_Posix_UnixSocketType_SOCK_DCCP            = 0x00000006,
+       #define Mono_Posix_UnixSocketType_SOCK_DCCP      Mono_Posix_UnixSocketType_SOCK_DCCP
+       Mono_Posix_UnixSocketType_SOCK_DGRAM           = 0x00000002,
+       #define Mono_Posix_UnixSocketType_SOCK_DGRAM     Mono_Posix_UnixSocketType_SOCK_DGRAM
+       Mono_Posix_UnixSocketType_SOCK_PACKET          = 0x0000000a,
+       #define Mono_Posix_UnixSocketType_SOCK_PACKET    Mono_Posix_UnixSocketType_SOCK_PACKET
+       Mono_Posix_UnixSocketType_SOCK_RAW             = 0x00000003,
+       #define Mono_Posix_UnixSocketType_SOCK_RAW       Mono_Posix_UnixSocketType_SOCK_RAW
+       Mono_Posix_UnixSocketType_SOCK_RDM             = 0x00000004,
+       #define Mono_Posix_UnixSocketType_SOCK_RDM       Mono_Posix_UnixSocketType_SOCK_RDM
+       Mono_Posix_UnixSocketType_SOCK_SEQPACKET       = 0x00000005,
+       #define Mono_Posix_UnixSocketType_SOCK_SEQPACKET Mono_Posix_UnixSocketType_SOCK_SEQPACKET
+       Mono_Posix_UnixSocketType_SOCK_STREAM          = 0x00000001,
+       #define Mono_Posix_UnixSocketType_SOCK_STREAM    Mono_Posix_UnixSocketType_SOCK_STREAM
+};
+int Mono_Posix_FromUnixSocketType (int x, int *r);
+int Mono_Posix_ToUnixSocketType (int x, int *r);
+
 enum Mono_Posix_WaitOptions {
        Mono_Posix_WaitOptions_WNOHANG         = 0x00000001,
        #define Mono_Posix_WaitOptions_WNOHANG   Mono_Posix_WaitOptions_WNOHANG
@@ -1481,6 +1800,7 @@ int Mono_Posix_ToXattrFlags (int x, int *r);
 
 struct Mono_Posix_Flock;
 struct Mono_Posix_Iovec;
+struct Mono_Posix_Linger;
 struct Mono_Posix_Pollfd;
 struct Mono_Posix_Stat;
 struct Mono_Posix_Statvfs;
@@ -1501,6 +1821,7 @@ struct Mono_Unix_UnixSignal_SignalInfo;
 
 struct flock;
 struct iovec;
+struct linger;
 struct pollfd;
 struct timespec;
 struct timeval;
@@ -1542,6 +1863,17 @@ int
 Mono_Posix_ToIovec (struct iovec *from, struct Mono_Posix_Iovec* to);
 
 
+struct Mono_Posix_Linger {
+       int l_onoff;
+       int l_linger;
+};
+
+int
+Mono_Posix_FromLinger (struct Mono_Posix_Linger* from, struct linger *to);
+int
+Mono_Posix_ToLinger (struct linger *from, struct Mono_Posix_Linger* to);
+
+
 struct Mono_Posix_Pollfd {
        int   fd;
        short events;
@@ -1755,6 +2087,8 @@ int Mono_Posix_Syscall_endpwent (void);
 int Mono_Posix_Syscall_endusershell (void);
 int Mono_Posix_Syscall_fcntl (int fd, int cmd);
 int Mono_Posix_Syscall_fcntl_arg (int fd, int cmd, gint64 arg);
+int Mono_Posix_Syscall_fcntl_arg_int (int fd, int cmd, int arg);
+int Mono_Posix_Syscall_fcntl_arg_ptr (int fd, int cmd, void* ptr);
 int Mono_Posix_Syscall_fcntl_lock (int fd, int cmd, struct Mono_Posix_Flock* lock);
 int Mono_Posix_Syscall_fgetgrent (void* stream, struct Mono_Posix_Syscall__Group* grbuf);
 int Mono_Posix_Syscall_fgetpwent (void* stream, struct Mono_Posix_Syscall__Passwd* pwbuf);
@@ -1790,6 +2124,9 @@ int Mono_Posix_Syscall_getpwnam (const char* name, struct Mono_Posix_Syscall__Pa
 int Mono_Posix_Syscall_getpwnam_r (const char* name, struct Mono_Posix_Syscall__Passwd* pwbuf, void** pwbufp);
 int Mono_Posix_Syscall_getpwuid (unsigned int uid, struct Mono_Posix_Syscall__Passwd* passwd);
 int Mono_Posix_Syscall_getpwuid_r (unsigned int uid, struct Mono_Posix_Syscall__Passwd* pwbuf, void** pwbufp);
+int Mono_Posix_Syscall_getsockopt (int socket, int level, int option_name, void* option_value, gint64* option_len);
+int Mono_Posix_Syscall_getsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value);
+int Mono_Posix_Syscall_getsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value);
 int Mono_Posix_Syscall_gettimeofday (struct Mono_Posix_Timeval* tv, void* ignore);
 gint64 Mono_Posix_Syscall_getxattr (const char* path, const char* name, unsigned char* value, guint64 size);
 int Mono_Posix_Syscall_L_ctermid (void);
@@ -1833,10 +2170,12 @@ int Mono_Posix_Syscall_readdir_r (void* dirp, struct Mono_Posix_Syscall__Dirent*
 gint64 Mono_Posix_Syscall_readlink (const char* path, unsigned char* buf, guint64 bufsiz);
 gint64 Mono_Posix_Syscall_readlinkat (int dirfd, const char* pathname, unsigned char* buf, guint64 bufsiz);
 gint64 Mono_Posix_Syscall_readv (int fd, struct Mono_Posix_Iovec* iov, int iovcnt);
+gint64 Mono_Posix_Syscall_recv (int socket, void* buffer, guint64 length, int flags);
 int Mono_Posix_Syscall_remap_file_pages (void* start, guint64 size, int prot, gint64 pgoff, int flags);
 int Mono_Posix_Syscall_removexattr (const char* path, const char* name);
 int Mono_Posix_Syscall_rewinddir (void* dir);
 int Mono_Posix_Syscall_seekdir (void* dir, gint64 offset);
+gint64 Mono_Posix_Syscall_send (int socket, void* message, guint64 length, int flags);
 gint64 Mono_Posix_Syscall_sendfile (int out_fd, int in_fd, gint64* offset, guint64 count);
 int Mono_Posix_Syscall_setdomainname (const char* name, guint64 len);
 int Mono_Posix_Syscall_setfsent (void);
@@ -1845,9 +2184,13 @@ int Mono_Posix_Syscall_setgroups (guint64 size, unsigned int* list);
 int Mono_Posix_Syscall_sethostid (gint64 hostid);
 int Mono_Posix_Syscall_sethostname (const char* name, guint64 len);
 int Mono_Posix_Syscall_setpwent (void);
+int Mono_Posix_Syscall_setsockopt (int socket, int level, int option_name, void* option_value, gint64 option_len);
+int Mono_Posix_Syscall_setsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value);
+int Mono_Posix_Syscall_setsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value);
 int Mono_Posix_Syscall_settimeofday (struct Mono_Posix_Timeval* tv, struct Mono_Posix_Timezone* tz);
 int Mono_Posix_Syscall_setusershell (void);
 int Mono_Posix_Syscall_setxattr (const char* path, const char* name, unsigned char* value, guint64 size, int flags);
+int Mono_Posix_Syscall_socketpair (int domain, int type, int protocol, int* socket1, int* socket2);
 int Mono_Posix_Syscall_stat (const char* file_name, struct Mono_Posix_Stat* buf);
 int Mono_Posix_Syscall_statvfs (const char* path, struct Mono_Posix_Statvfs* buf);
 int Mono_Posix_Syscall_stime (gint64* t);
index aedff01b7f32d6f8ce7f2a570c0472afa6e48c6e..cb5d94131da010bec4af329b7495109199948641 100644 (file)
@@ -149,6 +149,13 @@ typedef gint64 suseconds_t;
                return ret; \
        }}G_STMT_END
 
+#define mph_have_uint_overflow(var) ((var) < 0 || (var) > UINT_MAX)
+
+#define mph_return_val_if_uint_overflow(var, ret) \
+       _mph_return_val_if_cb_(var, ret, mph_have_uint_overflow)
+
+#define mph_return_if_uint_overflow(var) mph_return_val_if_uint_overflow(var, -1)
+
 #define mph_have_long_overflow(var) ((var) > LONG_MAX || (var) < LONG_MIN)
 
 #define mph_return_val_if_long_overflow(var, ret) \
@@ -156,14 +163,14 @@ typedef gint64 suseconds_t;
 
 #define mph_return_if_long_overflow(var) mph_return_val_if_long_overflow(var, -1)
 
-#define mph_have_ulong_overflow(var) ((var) > ULONG_MAX)
+#define mph_have_ulong_overflow(var) (var) < 0 || ((var) > ULONG_MAX)
 
 #define mph_return_val_if_ulong_overflow(var, ret) \
        _mph_return_val_if_cb_(var, ret, mph_have_ulong_overflow)
 
 #define mph_return_if_ulong_overflow(var) mph_return_val_if_ulong_overflow(var, -1)
 
-#define mph_have_size_t_overflow(var) ((var) > MPH_SIZE_T_MAX)
+#define mph_have_size_t_overflow(var) ((var) < 0 || (var) > MPH_SIZE_T_MAX)
 
 #define mph_return_val_if_size_t_overflow(var, ret) \
        _mph_return_val_if_cb_(var, ret, mph_have_size_t_overflow)
@@ -185,6 +192,8 @@ typedef gint64 suseconds_t;
 
 #define mph_return_if_time_t_overflow(var) mph_return_if_long_overflow(var)
 
+#define mph_return_if_socklen_t_overflow(var) mph_return_if_uint_overflow(var)
+
 #define mph_return_if_val_in_list5(var,a,b,c,d,e) \
        do {                                                            \
                int v = (var);                                                \
diff --git a/support/sys-socket.c b/support/sys-socket.c
new file mode 100644 (file)
index 0000000..188df56
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * <sys/socket.h> wrapper functions.
+ *
+ * Authors:
+ *   Steffen Kiess (s-kiess@web.de)
+ *
+ * Copyright (C) 2015 Steffen Kiess
+ */
+
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#include <stddef.h>
+
+#include "map.h"
+#include "mph.h"
+
+G_BEGIN_DECLS
+
+int
+Mono_Posix_Syscall_socketpair (int domain, int type, int protocol, int* socket1, int* socket2)
+{
+       int filedes[2] = {-1, -1};
+       int r;
+
+       r = socketpair (domain, type, protocol, filedes);
+
+       *socket1 = filedes[0];
+       *socket2 = filedes[1];
+       return r;
+}
+
+int
+Mono_Posix_Syscall_getsockopt (int socket, int level, int option_name, void* option_value, gint64* option_len)
+{
+       socklen_t len;
+       int r;
+
+       mph_return_if_socklen_t_overflow (*option_len);
+
+       len = *option_len;
+
+       r = getsockopt (socket, level, option_name, option_value, &len);
+
+       *option_len = len;
+
+       return r;
+}
+
+int
+Mono_Posix_Syscall_getsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value)
+{
+       struct timeval tv;
+       int r;
+       socklen_t size;
+
+       size = sizeof (struct timeval);
+       r = getsockopt (socket, level, option_name, &tv, &size);
+
+       if (r != -1 && size == sizeof (struct timeval)) {
+               if (Mono_Posix_ToTimeval (&tv, option_value) != 0)
+                       return -1;
+       } else {
+               memset (option_value, 0, sizeof (struct Mono_Posix_Timeval));
+               if (r != -1)
+                       errno = EINVAL;
+       }
+
+       return r;
+}
+
+int
+Mono_Posix_Syscall_getsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value)
+{
+       struct linger ling;
+       int r;
+       socklen_t size;
+
+       size = sizeof (struct linger);
+       r = getsockopt (socket, level, option_name, &ling, &size);
+
+       if (r != -1 && size == sizeof (struct linger)) {
+               if (Mono_Posix_ToLinger (&ling, option_value) != 0)
+                       return -1;
+       } else {
+               memset (option_value, 0, sizeof (struct Mono_Posix_Linger));
+               if (r != -1)
+                       errno = EINVAL;
+       }
+
+       return r;
+}
+
+int
+Mono_Posix_Syscall_setsockopt (int socket, int level, int option_name, void* option_value, gint64 option_len)
+{
+       mph_return_if_socklen_t_overflow (option_len);
+
+       return setsockopt (socket, level, option_name, option_value, option_len);
+}
+
+int
+Mono_Posix_Syscall_setsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value)
+{
+       struct timeval tv;
+
+       if (Mono_Posix_FromTimeval (option_value, &tv) != 0)
+               return -1;
+
+       return setsockopt (socket, level, option_name, &tv, sizeof (struct timeval));
+}
+
+int
+Mono_Posix_Syscall_setsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value)
+{
+       struct linger ling;
+
+       if (Mono_Posix_FromLinger (option_value, &ling) != 0)
+               return -1;
+
+       return setsockopt (socket, level, option_name, &ling, sizeof (struct linger));
+}
+
+gint64
+Mono_Posix_Syscall_recv (int socket, void* message, guint64 length, int flags)
+{
+       mph_return_if_size_t_overflow (length);
+
+       return recv (socket, message, length, flags);
+}
+
+gint64
+Mono_Posix_Syscall_send (int socket, void* message, guint64 length, int flags)
+{
+       mph_return_if_size_t_overflow (length);
+
+       return send (socket, message, length, flags);
+}
index 27e774f066cf401299ef8f9e2b699ce92e12de44..b30a3eb1c8e67f4e8ef9cd171b1dc6971f53fa99 100644 (file)
 #error Unknown architecture
 #endif
 
+#define WINVER 0x0A00
+
+#include <SDKDDKVer.h>
+
 #if _WIN32_WINNT < 0x0600
 #error "Mono requires Windows Vista or later"
 #endif /* _WIN32_WINNT < 0x0600 */