Merge pull request #4630 from BrzVlad/feature-valloc-limit
authorVlad Brezae <brezaevlad@gmail.com>
Tue, 4 Apr 2017 23:52:03 +0000 (02:52 +0300)
committerGitHub <noreply@github.com>
Tue, 4 Apr 2017 23:52:03 +0000 (02:52 +0300)
[sgen] OOM testing

149 files changed:
Makefile.am
configure.ac
eglib/src/gfile-unix.c
eglib/src/glib.h
eglib/src/gmisc-unix.c
eglib/src/gmisc-win32.c
external/binary-reference-assemblies
external/cecil
external/corefx
mcs/build/profiles/basic.make
mcs/build/profiles/orbis.make
mcs/build/rules.make
mcs/class/Facades/System.Threading.Overlapped/Makefile
mcs/class/Facades/System.Threading.Overlapped/System.Threading.Overlapped.dll.sources
mcs/class/Facades/System.Threading.Overlapped/TypeForwarders.cs
mcs/class/Facades/System.Threading.Overlapped/corefx/SR.cs [deleted file]
mcs/class/Makefile
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Loop.cs
mcs/class/System.Core/testing_aot_full_System.Core.dll.sources
mcs/class/System.Core/testing_aot_hybrid_System.Core.dll.sources
mcs/class/System.Security/orbis_System.Security.dll.sources [new file with mode: 0644]
mcs/class/System.Web/System.Web-net_4_x.csproj
mcs/class/System.Web/System.Web-plainweb-net_4_x.csproj
mcs/class/System.Web/System.Web.Hosting/HostingEnvironment.cs
mcs/class/System.Web/System.Web.dll.sources
mcs/class/System/Makefile
mcs/class/System/Mono.Net.Security/SystemCertificateValidator.cs
mcs/class/System/System-bare-net_4_x.csproj
mcs/class/System/System-net_4_x.csproj
mcs/class/System/System-secxml-net_4_x.csproj
mcs/class/System/System.IO.Compression/DeflateStream.cs
mcs/class/System/System.Net.NetworkInformation/IPGlobalProperties.cs
mcs/class/System/System.Net.NetworkInformation/NetworkChange.cs
mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs
mcs/class/System/System.Net.NetworkInformation/Ping.cs
mcs/class/System/System.Net.Security/SslStream.cs
mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs [deleted file]
mcs/class/System/System.Net.WebSockets/ClientWebSocket.platformnotsupported.cs [deleted file]
mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs [deleted file]
mcs/class/System/System.Net.WebSockets/HttpListenerWebSocketContext.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocket.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketContext.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketError.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketException.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs [deleted file]
mcs/class/System/System.Net.WebSockets/WebSocketState.cs [deleted file]
mcs/class/System/System.Net/MacProxy.cs
mcs/class/System/System/Platform.cs
mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs
mcs/class/System/common.sources
mcs/class/System/corefx/SR.cs
mcs/class/System/monotouch_watch_System.dll.sources
mcs/class/System/orbis_System.dll.exclude.sources [new file with mode: 0644]
mcs/class/WindowsBase/System.IO.Packaging/PackagePart.cs
mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs
mcs/class/corlib/System/Array.cs
mcs/class/corlib/corert/Array.Portable.cs
mcs/class/reference-assemblies/Makefile
mcs/class/referencesource/System/net/System/Net/webproxy.cs
mcs/mcs/ikvm.cs
mcs/tools/xbuild/frameworks/net_4.5.1.xml
mcs/tools/xbuild/frameworks/net_4.5.2.xml
mcs/tools/xbuild/frameworks/net_4.6.1.xml
mcs/tools/xbuild/frameworks/net_4.6.2.xml
mcs/tools/xbuild/frameworks/net_4.6.xml
mono/arch/ia64/codegen.c
mono/cil/cil-opcodes.xml
mono/cil/opcode.def
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/boehm-gc.c
mono/metadata/class.c
mono/metadata/cominterop.c
mono/metadata/console-null.c
mono/metadata/console-unix.c
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/image.c
mono/metadata/locales.c
mono/metadata/lock-tracer.c
mono/metadata/marshal.c
mono/metadata/marshal.h
mono/metadata/mono-config.c
mono/metadata/sgen-mono.c
mono/metadata/sgen-stw.c
mono/metadata/threadpool-io.c
mono/metadata/w32file-unix.c
mono/mini/Makefile.am.in
mono/mini/aot-runtime.c
mono/mini/debugger-agent.c
mono/mini/decompose.c
mono/mini/driver.c
mono/mini/exceptions.cs
mono/mini/helpers.c
mono/mini/iltests.il
mono/mini/interp/interp-internals.h
mono/mini/interp/interp.c
mono/mini/interp/interp.h
mono/mini/interp/mintops.def
mono/mini/interp/transform.c
mono/mini/ir-emit.h
mono/mini/liveness.c
mono/mini/llvm-jit.cpp
mono/mini/method-to-ir.c
mono/mini/mini-arm.c
mono/mini/mini-cross-helpers.c
mono/mini/mini-gc.c
mono/mini/mini-generic-sharing.c
mono/mini/mini-llvm.c
mono/mini/mini-ppc.h
mono/mini/mini-runtime.c
mono/mini/mini-x86.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/mixed.cs [new file with mode: 0644]
mono/mini/objects.cs
mono/mini/tramp-amd64.c
mono/mini/tramp-ppc.c
mono/mini/type-checking.c
mono/profiler/mono-profiler-log.c
mono/sgen/sgen-cardtable.c
mono/sgen/sgen-copy-object.h
mono/sgen/sgen-gc.c
mono/sgen/sgen-gc.h
mono/sgen/sgen-gray.h
mono/sgen/sgen-marksweep.c
mono/sgen/sgen-memory-governor.c
mono/sgen/sgen-minor-copy-object.h
mono/sgen/sgen-minor-scan-object.h
mono/sgen/sgen-protocol.c
mono/sgen/sgen-simple-nursery.c
mono/sgen/sgen-split-nursery.c
mono/sgen/sgen-thread-pool.c
mono/sgen/sgen-thread-pool.h
mono/sgen/sgen-workers.c
mono/sgen/sgen-workers.h
mono/utils/checked-build.c
mono/utils/mono-hwcap.c
mono/utils/mono-io-portability.c
mono/utils/mono-log-common.c
mono/utils/mono-logger.c
mono/utils/mono-mmap.c
mono/utils/mono-rand.c
mono/utils/mono-threads-coop.c
mono/utils/mono-threads.c
mono/utils/strenc.c
scripts/ci/run-test-interpreter.sh

index 1dbe3b14a2ecd964a9bf9f6ce48492b3eed09520..ede769564985d5b87cdf226a5ee99e9783381c44 100644 (file)
@@ -44,10 +44,6 @@ dist-hook:
        rm -rf `find $(top_distdir)/external -path '*\.git'`
        rm -f `find $(top_distdir)/external -path '*\.exe' -not -path '*/roslyn-binaries/*'`
        rm -f `find $(top_distdir)/external -path '*\.dll' -not -path '*/binary-reference-assemblies/*' -not -path '*/roslyn-binaries/*'`
-       cp mcs/class/lib/basic/System.Configuration.dll mcs/class/lib/monolite/
-       cp mcs/class/lib/basic/System.Security.dll mcs/class/lib/monolite/
-# Disable this for now because it is very slow and causes wrench to timeout:
-#      test ! -d $(GIT_DIR) || ./scripts/commits-to-changelog.py --root=$(distdir) last-commit-with-compulsory-changelog-entry
 
 pkgconfigdir = $(libdir)/pkgconfig
 noinst_DATA = mono-uninstalled.pc
@@ -55,16 +51,13 @@ DISTCLEANFILES= mono-uninstalled.pc
 
 # building with monolite
 mcslib = $(mcs_topdir)/class/lib
-monolite = $(mcslib)/monolite
 monolite_url = https://download.mono-project.com/monolite/monolite-$(MONO_CORLIB_VERSION)-latest.tar.gz
 .PHONY: get-monolite-latest 
 get-monolite-latest:
-       -rm -fr $(mcslib)/monolite-*
-       -mkdir -p $(mcslib)
-       test ! -d $(monolite) || test ! -d $(monolite).old || rm -fr $(monolite).old
-       test ! -d $(monolite) || mv -f $(monolite) $(monolite).old
+       -rm -fr $(mcslib)/monolite/$(MONO_CORLIB_VERSION)
+       -mkdir -p $(mcslib)/monolite
        cd $(mcslib) && { (wget -O- $(monolite_url) || curl -L $(monolite_url)) | gzip -d | tar xf - ; }
-       cd $(mcslib) && mv -f monolite-* monolite
+       cd $(mcslib) && mv -f monolite-* monolite/$(MONO_CORLIB_VERSION)
 
 if BITCODE
 BITCODE_CHECK=yes
index bb1aecfa5ee583c8f59ec299599ca8582c06c7cb..ab8b0d9df601eac754bf1219e87e2064c35d5adf 100644 (file)
@@ -1,7 +1,7 @@
 # Process this file with autoconf to produce a configure script.
 #AC_PREREQ([2.62])
 
-AC_INIT(mono, [5.1.0],
+AC_INIT(mono, [5.3.0],
         [http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono])
 
 AC_CONFIG_SRCDIR([README.md])
@@ -2407,6 +2407,8 @@ if test x$host_win32 = xno; then
        AC_CHECK_FUNCS(system)
        AC_CHECK_FUNCS(fork execv execve)
        AC_CHECK_FUNCS(accept4)
+       AC_CHECK_FUNCS(localtime_r)
+       AC_CHECK_FUNCS(mkdtemp)
        AC_CHECK_SIZEOF(size_t)
        AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], , 
                [#include <sys/types.h>
index 9c34d8756930f4fa7e898995c1d02329843f1be9..ab1fbb483bd53d995c6b86f216655563cfc2b757 100644 (file)
@@ -82,7 +82,11 @@ g_file_test (const gchar *filename, GFileTest test)
 gchar *
 g_mkdtemp (char *tmp_template)
 {
+#ifdef HAVE_MKDTEMP
        char *template_copy = g_strdup (tmp_template);
 
        return mkdtemp (template_copy);
+#else
+       g_error("Function not supported");
+#endif
 }
index 8ceec487041d6bb7c3a2a72d3f8e85cfd2ecaa78..6f16fcb292bb692f2e2fc5daa5d7c3a5a8cd0189 100644 (file)
@@ -160,7 +160,8 @@ typedef struct _GMemChunk GMemChunk;
  * Misc.
  */
 
-const gchar *    g_getenv(const gchar *variable);
+gboolean         g_hasenv(const gchar *variable);
+gchar *          g_getenv(const gchar *variable);
 gboolean         g_setenv(const gchar *variable, const gchar *value, gboolean overwrite);
 void             g_unsetenv(const gchar *variable);
 
index 273024871c5f890e01410f8a12094cf256cd33d8..2529069a981047ac63b392340c801857ca4760d4 100644 (file)
 #include <unistd.h>
 #endif
 
+static pthread_mutex_t env_lock = PTHREAD_MUTEX_INITIALIZER;
 
-const gchar *
-g_getenv(const gchar *variable)
+/* MONO Comment
+ * 
+ * As per the UNIX spec, 
+ * "The return value from getenv() may point to static data which may be overwritten by subsequent calls to getenv(), setenv(), or unsetenv()."
+ * Source: Unix Manual Pages for getenv, IEEE Std 1003.1
+ *
+ * This means that using pointers returned from getenv may (and does) lead to many
+ * pointers which refer to the same piece of memory. When one is freed, all will be freed.
+ *
+ * This is unsafe and an ergonomics risk to fix in the callers. While the caller could lock,
+ * this introduces the risk for looping or exiting while inside of a lock. For this reason,
+ * g_getenv does not mimic the behavior of POSIX getenv anymore.
+ *
+ * The memory address returned will be unique to the invocaton, and must be freed.
+ * */ 
+gchar *
+g_getenv (const gchar *variable)
+{
+       gchar *ret = NULL;
+       pthread_mutex_lock (&env_lock);
+       gchar *res = getenv(variable);
+       if (res)
+               ret = g_strdup(res);
+       pthread_mutex_unlock (&env_lock);
+
+       return ret;
+}
+
+/*
+ * This function checks if the given variable is non-NULL
+ * in the environment. It's useful because it removes memory
+ * freeing requirements.
+ *
+ */
+gboolean
+g_hasenv (const gchar *variable)
 {
-       return getenv(variable);
+       pthread_mutex_lock (&env_lock);
+       gchar *res = getenv(variable);
+       gboolean not_null = (res != NULL);
+       pthread_mutex_unlock (&env_lock);
+
+       return not_null;
 }
 
 gboolean
 g_setenv(const gchar *variable, const gchar *value, gboolean overwrite)
 {
-       return setenv(variable, value, overwrite) == 0;
+       gboolean res;
+       pthread_mutex_lock (&env_lock);
+       res = (setenv(variable, value, overwrite) == 0);
+       pthread_mutex_unlock (&env_lock);
+       return res;
 }
 
 void
 g_unsetenv(const gchar *variable)
 {
+       pthread_mutex_lock (&env_lock);
        unsetenv(variable);
+       pthread_mutex_unlock (&env_lock);
 }
 
 gchar*
index 4aac0ef69460fe70c432dfb78f8fcfd2bd931f5a..70d99bfb94980487f147e7b39231154056ca4508 100644 (file)
 #include <io.h>
 #include <assert.h>
 
-const gchar *
+gboolean
+g_hasenv (const gchar *variable)
+{
+       return g_getenv (variable) != NULL;
+}
+
+gchar *
 g_getenv(const gchar *variable)
 {
        gunichar2 *var, *buffer;
index 6c77197318fe85dfddf75a1b344b9bf8d0007b0b..febc100f0313f0dc9d75dd1bcea45e87134b5b55 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6c77197318fe85dfddf75a1b344b9bf8d0007b0b
+Subproject commit febc100f0313f0dc9d75dd1bcea45e87134b5b55
index 229946f543f65db2b102188427cda4b68fc08ee6..5f93431f2d699e9b090a5a14db5941a18b1e171b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 229946f543f65db2b102188427cda4b68fc08ee6
+Subproject commit 5f93431f2d699e9b090a5a14db5941a18b1e171b
index f646c9d6a61cfc067df42b0e452448c4da7d144b..78360b22e71b70de1d8cc9588cb4ef0040449c31 160000 (submodule)
@@ -1 +1 @@
-Subproject commit f646c9d6a61cfc067df42b0e452448c4da7d144b
+Subproject commit 78360b22e71b70de1d8cc9588cb4ef0040449c31
index 2b822234f612322bb2a8c03290bcf2dcb120d2dd..1e5edbca35512ba2fd936643af62208350906153 100644 (file)
@@ -1,15 +1,17 @@
 # -*- makefile -*-
 
-with_mono_path_monolite = MONO_PATH="$(topdir)/class/lib/monolite$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/monolite/Facades$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH"
+monolite_path := $(topdir)/class/lib/monolite/$(MONO_CORLIB_VERSION)
+
+with_mono_path_monolite = MONO_PATH="$(monolite_path)$(PLATFORM_PATH_SEPARATOR)$(monolite_path)/Facades$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH"
 
 monolite_flag := $(depsdir)/use-monolite
 use_monolite := $(wildcard $(monolite_flag))
 
-MONOLITE_MSCORLIB = $(topdir)/class/lib/monolite/mscorlib.dll
+MONOLITE_MSCORLIB = $(monolite_path)/mscorlib.dll
 
 ifdef use_monolite
 ifdef MCS_MODE
-       CSC_LOCATION = $(topdir)/class/lib/monolite/mcs.exe
+       CSC_LOCATION = $(monolite_path)/mcs.exe
 endif
 
 PROFILE_RUNTIME = $(with_mono_path_monolite) $(RUNTIME)
@@ -79,8 +81,7 @@ do-profile-check: $(depsdir)/.stamp
                $(MAKE) $(MAKE_Q) do-profile-check-monolite ; \
            else \
                echo "*** The runtime '$(PROFILE_RUNTIME)' doesn't appear to be usable." 1>&2; \
-                echo "*** You need Mono version 4.8 or better installed to build MCS" 1>&2 ; \
-                echo "*** Check mono README for information on how to bootstrap a Mono installation." 1>&2 ; \
+                echo "*** Check README for information on how to bootstrap a Mono installation." 1>&2 ; \
                exit 1; fi; fi
 
 
@@ -89,7 +90,7 @@ ifdef use_monolite
 do-get-monolite:
 
 do-profile-check-monolite:
-       @echo "*** The contents of your 'monolite' directory may be out-of-date" 1>&2
+       @echo "*** The contents of your 'monolite/$(MONO_CORLIB_VERSION)' directory may be out-of-date" 1>&2
        @echo "*** You may want to try 'make get-monolite-latest'" 1>&2
        rm -f $(monolite_flag)
        exit 1
@@ -97,12 +98,12 @@ do-profile-check-monolite:
 else
 
 do-get-monolite:
-       @echo "*** Downloading bootstrap required 'monolite'" 1>&2
+       @echo "*** Downloading bootstrap required 'monolite/$(MONO_CORLIB_VERSION)'" 1>&2
        $(MAKE) $(MAKE_Q) -C $(mono_build_root) get-monolite-latest
 
 do-profile-check-monolite: $(depsdir)/.stamp
        @echo "*** The runtime '$(PROFILE_RUNTIME)' doesn't appear to be usable." 1>&2
-       @echo "*** Trying the 'monolite' directory." 1>&2
+       @echo "*** Trying the 'monolite/$(MONO_CORLIB_VERSION)' directory." 1>&2
        @echo dummy > $(monolite_flag)
        $(MAKE) do-profile-check
 
index a43693e04b37a3f79ab77743e051bb2f213c880a..2a73e5139cb0bf4c53a4594fd99b7308915fe05e 100644 (file)
@@ -24,6 +24,7 @@ PROFILE_MCS_FLAGS = \
        -d:MOBILE,MOBILE_LEGACY \
        -d:FULL_AOT_DESKTOP     \
        -d:FULL_AOT_RUNTIME \
+       -d:ORBIS \
        -d:DISABLE_REMOTING \
        -d:DISABLE_COM \
        -nowarn:1699 \
@@ -40,6 +41,7 @@ ALWAYS_AOT = yes
 MOBILE_PROFILE = yes
 NO_VTS_TEST = yes
 NO_CONSOLE = yes
+PROFILE_DISABLE_BTLS = yes
 
 # Note need for trailing comma. If you add, keep it
 PROFILE_TEST_HARNESS_EXCLUDES = MobileNotWorking,PKITS,
index 12dcb28ac98a1d2f0105fb1c36f4808417bdb84a..2ee6460b949118bd9e031c19a02d50dc9f72efb5 100644 (file)
@@ -33,7 +33,7 @@ USE_MCS_FLAGS = /codepage:$(CODEPAGE) /nologo /noconfig /deterministic $(LOCAL_M
 USE_MBAS_FLAGS = /codepage:$(CODEPAGE) $(LOCAL_MBAS_FLAGS) $(PLATFORM_MBAS_FLAGS) $(PROFILE_MBAS_FLAGS) $(MBAS_FLAGS)
 USE_CFLAGS = $(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS)
 CSCOMPILE = $(Q_MCS) $(MCS) $(USE_MCS_FLAGS)
-CSC_RUNTIME_FLAGS = --aot-path=$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE) --gc-params=nursery-size=64m
+CSC_RUNTIME_FLAGS = --aot-path=$(abspath $(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)) --gc-params=nursery-size=64m
 BASCOMPILE = $(MBAS) $(USE_MBAS_FLAGS)
 CCOMPILE = $(CC) $(USE_CFLAGS)
 BOOT_COMPILE = $(Q_MCS) $(BOOTSTRAP_MCS) $(USE_MCS_FLAGS)
index 71630db2e941bd6fe73fb448eef528076cd020ed..44d534b1843689eeca0caa4251761b63662db264 100644 (file)
@@ -12,10 +12,9 @@ LIBRARY = System.Threading.Overlapped.dll
 KEY_FILE = ../../msfinal.pub
 SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS) -unsafe -nowarn:3021
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-RESX_RESOURCE_STRING = \
-    ../../../../external/corefx/src/System.Threading.Overlapped/src/Resources/Strings.resx
+PLATFORM_DEBUG_FLAGS =
 
 NO_TEST = yes
 
index a8d9932de857bdab5f5acd7e50cf571417ea0ec9..719628dc7c61ac7d0444434320134bf5305b7f73 100644 (file)
@@ -1,10 +1,2 @@
 TypeForwarders.cs
 AssemblyInfo.cs
-
-corefx/SR.cs
-
-../../../../external/corefx/src/Common/src/System/HResults.cs
-../../../../external/corefx/src/System.Threading.Overlapped/src/System/Threading/ClrThreadPoolBoundHandle.cs
-../../../../external/corefx/src/System.Threading.Overlapped/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs
-../../../../external/corefx/src/System.Threading.Overlapped/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs
-../../../../external/corefx/src/System.Threading.Overlapped/src/System/Threading/DeferredDisposableLifetime.cs
index dd272df5d996c56f703f0c19bfc8ee24d818b964..6610d8849e04c02e163be58b2ebd58daf1215f05 100644 (file)
@@ -22,3 +22,5 @@
 
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.IOCompletionCallback))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.NativeOverlapped))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.PreAllocatedOverlapped))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ThreadPoolBoundHandle))]
diff --git a/mcs/class/Facades/System.Threading.Overlapped/corefx/SR.cs b/mcs/class/Facades/System.Threading.Overlapped/corefx/SR.cs
deleted file mode 100644 (file)
index 7c2846a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// This file was generated by resx2sr tool
-//
-
-partial class SR
-{
-       public const string Argument_AlreadyBoundOrSyncHandle = "'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.";
-       public const string Argument_InvalidHandle = "'handle' has been disposed or is an invalid handle.";
-       public const string Argument_NativeOverlappedAlreadyFree = "'overlapped' has already been freed.";
-       public const string Argument_NativeOverlappedWrongBoundHandle = "'overlapped' was not allocated by this ThreadPoolBoundHandle instance.";
-       public const string Argument_PreAllocatedAlreadyAllocated = "'preAllocated' is already in use.";
-       public const string InvalidOperation_NativeOverlappedReused = "NativeOverlapped cannot be reused for multiple operations.";
-}
index 3f981f77aba50c4f2f1a4a430cff729bf516cc23..5463f65160f305ace1e967b1275821aa213b18f2 100644 (file)
@@ -335,6 +335,11 @@ xbuild_4_0_dirs := \
        $(xbuild_2_0_dirs)      \
        Microsoft.Build
 
+orbis_exclude_dirs := \
+       Microsoft.CSharp \
+       Mono.CSharp \
+       Mono.Data.Sqlite
+
 monodroid_SUBDIRS := $(monodroid_dirs)
 monotouch_SUBDIRS := $(monotouch_dirs)
 monotouch_watch_SUBDIRS := $(monotouch_watch_dirs)
@@ -352,7 +357,7 @@ net_4_x_PARALLEL_SUBDIRS := $(net_4_x_parallel_dirs)
 xbuild_12_SUBDIRS := $(xbuild_4_0_dirs)
 xbuild_14_SUBDIRS := $(xbuild_4_0_dirs) Microsoft.NuGet.Build.Tasks
 winaot_SUBDIRS := $(winaot_dirs)
-orbis_SUBDIRS := $(monotouch_dirs)
+orbis_SUBDIRS := $(filter-out $(orbis_exclude_dirs),$(monotouch_dirs))
 
 include ../build/rules.make
 
@@ -391,7 +396,7 @@ all-local $(STD_TARGETS:=-local):
 
 all-local-aot:
 
-monolite_dir := monolite
+monolite_dir := monolite/$(MONO_CORLIB_VERSION)
 
 # Files needed to bootstrap C# compiler
 build_files = mscorlib.dll System.dll System.Xml.dll Mono.Security.dll System.Core.dll System.Security.dll System.Configuration.dll \
index 1b254ef457aaafbfafc0ed3f47d6125193c503ba..ae456c5a3e5dc71b4825183ecf4752485336c34e 100644 (file)
@@ -36,46 +36,50 @@ using NUnit.Framework;
 namespace MonoTests.System.Linq.Expressions {
 
        [TestFixture]
-       public class ExpressionTest_Loop {
+       public class ExpressionTest_Loop
+       {
+               public static void Print (int arg)
+               {
+               }
 
                [Test]
                public void ComplexTest ()
                {
-            var breakLabel = Expression.Label ("LoopBreak");
-            var counter = Expression.Variable (typeof (int), "counter");
+                       var breakLabel = Expression.Label ("LoopBreak");
+                       var counter = Expression.Variable (typeof (int), "counter");
 
-            var l = Expression.Block (new[] { counter },
-                Expression.Assign (counter, Expression.Constant (-1)),
-                Expression.Loop (
-                Expression.Block (Expression.IfThenElse (
-                    Expression.Equal (Expression.Assign (counter, Expression.Add (counter, Expression.Constant (1))), Expression.Constant (1000)),
-                    Expression.Block (Expression.Break (breakLabel)),
-                    Expression.Call (null, typeof (Console).GetMethod ("WriteLine", new Type[] { typeof (int) }), counter)
-                )),
-                breakLabel)
-           );
+                       var l = Expression.Block (new[] { counter },
+                               Expression.Assign (counter, Expression.Constant (-1)),
+                               Expression.Loop (
+                               Expression.Block (Expression.IfThenElse (
+                                       Expression.Equal (Expression.Assign (counter, Expression.Add (counter, Expression.Constant (1))), Expression.Constant (1000)),
+                                       Expression.Block (Expression.Break (breakLabel)),
+                                       Expression.Call (null, typeof (ExpressionTest_Loop).GetMethod ("Print", new Type[] { typeof (int) }), counter)
+                               )),
+                               breakLabel)
+                  );
 
-            var res = Expression.Lambda<Action> (l).Compile ();
-        }
+                       var res = Expression.Lambda<Action> (l).Compile ();
+               }
 
                [Test]
                public void ComplexTest_2 ()
                {
-            var breakLabel = Expression.Label ("LoopBreak");
-            var counter = Expression.Variable (typeof (int), "counter");
+                       var breakLabel = Expression.Label ("LoopBreak");
+                       var counter = Expression.Variable (typeof (int), "counter");
 
-            var l = Expression.Block (new[] { counter },
-                Expression.Assign (counter, Expression.Constant(-1)),
-                Expression.Loop (
-                Expression.IfThenElse (
-                    Expression.Equal (Expression.Assign (counter, Expression.Add (counter, Expression.Constant (1))), Expression.Constant (1000)),
-                    Expression.Break (breakLabel),
-                    Expression.Call (null, typeof (Console).GetMethod ("WriteLine", new Type[] { typeof (int) }), counter)
-                ),
-                breakLabel)
-           );
+                       var l = Expression.Block (new[] { counter },
+                               Expression.Assign (counter, Expression.Constant(-1)),
+                               Expression.Loop (
+                               Expression.IfThenElse (
+                                       Expression.Equal (Expression.Assign (counter, Expression.Add (counter, Expression.Constant (1))), Expression.Constant (1000)),
+                                       Expression.Break (breakLabel),
+                                       Expression.Call (null, typeof (ExpressionTest_Loop).GetMethod ("Print", new Type[] { typeof (int) }), counter)
+                               ),
+                               breakLabel)
+                  );
 
-            var res = Expression.Lambda<Action> (l).Compile ();
+                       var res = Expression.Lambda<Action> (l).Compile ();
                }
        }
 }
index 8b8fef0e40e738565956982bb7c19e8fb8c0f9ee..70fa76793f398c59391c87ed80c7ebc55a4ec576 100644 (file)
@@ -6,11 +6,8 @@ System.Security.Cryptography/AesTransform.cs
 System.Security.Cryptography/MD5Cng.cs
 System.Security.Cryptography/SHA1Cng.cs
 System.Security.Cryptography/SHA256Cng.cs
-System.Security.Cryptography/SHA256CryptoServiceProvider.cs
 System.Security.Cryptography/SHA384Cng.cs
-System.Security.Cryptography/SHA384CryptoServiceProvider.cs
 System.Security.Cryptography/SHA512Cng.cs
-System.Security.Cryptography/SHA512CryptoServiceProvider.cs
 
 ../referencesource/System.Core/System/Security/Cryptography/AesManaged.cs
 ../referencesource/System.Core/System/Security/Cryptography/ECDiffieHellman.cs
index 11a92dbb1d2da72efb63504ffa56529cdc564557..c1ff8331787187d62ed7682967c5b5578b95724e 100644 (file)
@@ -6,11 +6,8 @@ System.Security.Cryptography/AesTransform.cs
 System.Security.Cryptography/MD5Cng.cs
 System.Security.Cryptography/SHA1Cng.cs
 System.Security.Cryptography/SHA256Cng.cs
-System.Security.Cryptography/SHA256CryptoServiceProvider.cs
 System.Security.Cryptography/SHA384Cng.cs
-System.Security.Cryptography/SHA384CryptoServiceProvider.cs
 System.Security.Cryptography/SHA512Cng.cs
-System.Security.Cryptography/SHA512CryptoServiceProvider.cs
 
 ../referencesource/System.Core/System/Security/Cryptography/AesManaged.cs
 ../referencesource/System.Core/System/Security/Cryptography/ECDiffieHellman.cs
diff --git a/mcs/class/System.Security/orbis_System.Security.dll.sources b/mcs/class/System.Security/orbis_System.Security.dll.sources
new file mode 100644 (file)
index 0000000..599b7fa
--- /dev/null
@@ -0,0 +1 @@
+#include common_System.Security.dll.sources
index 0fbe30a82553942d3077c81e0408b11e46c2b31d..33594b8bb1dec483f8992daa61076f8ba4adfe45 100644 (file)
     <Compile Include="..\referencesource\System.Web\Configuration\WebLevel.cs" />\r
     <Compile Include="..\referencesource\System.Web\Configuration\XhtmlConformanceMode.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\AppDomainProtocolHandler.cs" />\r
+    <Compile Include="..\referencesource\System.Web\Hosting\BackgroundWorkScheduler.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\HostingEnvironmentException.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\HTTP_COOKED_URL.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\IApplicationHost.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\AppVerifierException.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\AssemblyUtil.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\BinaryCompatibility.cs" />\r
+    <Compile Include="..\referencesource\System.Web\Util\CancellationTokenHelper.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\DateTimeUtil.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\Debug.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\DisposableAction.cs" />\r
index f4f056d83333df6b22b70b32e33e382f05fb00d7..bd51042b5fa10d1da160427043e6e02d44b6489c 100644 (file)
     <Compile Include="..\referencesource\System.Web\Configuration\WebLevel.cs" />\r
     <Compile Include="..\referencesource\System.Web\Configuration\XhtmlConformanceMode.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\AppDomainProtocolHandler.cs" />\r
+    <Compile Include="..\referencesource\System.Web\Hosting\BackgroundWorkScheduler.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\HostingEnvironmentException.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\HTTP_COOKED_URL.cs" />\r
     <Compile Include="..\referencesource\System.Web\Hosting\IApplicationHost.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\AppVerifierException.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\AssemblyUtil.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\BinaryCompatibility.cs" />\r
+    <Compile Include="..\referencesource\System.Web\Util\CancellationTokenHelper.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\DateTimeUtil.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\Debug.cs" />\r
     <Compile Include="..\referencesource\System.Web\Util\DisposableAction.cs" />\r
index 4b8a52f036de2deb44f292da94fd47541e04a425..2894a9009760fc7330bcedf7761d740fa77bb8e6 100644 (file)
 
 
 using System;
+using System.Collections.Generic;
 using System.Globalization;
+using System.Linq;
 using System.Security.Permissions;
 using System.Threading;
+using System.Threading.Tasks;
 using System.Web.Configuration;
 using System.Web.Caching;
 using System.Web.Util;
@@ -53,6 +56,8 @@ namespace System.Web.Hosting {
                static VirtualPathProvider vpath_provider = (HttpRuntime.AppDomainAppVirtualPath == null) ? null :
                                                                new DefaultVirtualPathProvider ();
                static int busy_count;
+               static BackgroundWorkScheduler _backgroundWorkScheduler = null; // created on demand
+               static readonly Task<object> _completedTask = Task.FromResult<object>(null);
 
                internal static bool HaveCustomVPP {
                        get;
@@ -212,6 +217,73 @@ namespace System.Web.Hosting {
                        if (Host != null)
                                Host.UnregisterObject (obj);
                }
+
+               // Schedules a task which can run in the background, independent of any request.
+               // This differs from a normal ThreadPool work item in that ASP.NET can keep track
+               // of how many work items registered through this API are currently running, and
+               // the ASP.NET runtime will try not to delay AppDomain shutdown until these work
+               // items have finished executing.
+               //
+               // Usage notes:
+               // - This API cannot be called outside of an ASP.NET-managed AppDomain.
+               // - The caller's ExecutionContext is not flowed to the work item.
+               // - Scheduled work items are not guaranteed to ever execute, e.g., when AppDomain
+               //   shutdown has already started by the time this API was called.
+               // - The provided CancellationToken will be signaled when the application is
+               //   shutting down. The work item should make every effort to honor this token.
+               //   If a work item does not honor this token and continues executing it will
+               //   eventually be considered rogue, and the ASP.NET runtime will rudely unload
+               //   the AppDomain without waiting for the work item to finish.
+               //
+               // This overload of QueueBackgroundWorkItem takes a void-returning callback; the
+               // work item will be considered finished when the callback returns.
+               [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
+               public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem) {
+                       if (workItem == null) {
+                               throw new ArgumentNullException("workItem");
+                       }
+
+                       QueueBackgroundWorkItem(ct => { workItem(ct); return _completedTask; });
+               }
+
+               // See documentation on the other overload for a general API overview.
+               //
+               // This overload of QueueBackgroundWorkItem takes a Task-returning callback; the
+               // work item will be considered finished when the returned Task transitions to a
+               // terminal state.
+               [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
+               public static void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem) {
+                       if (workItem == null) {
+                               throw new ArgumentNullException("workItem");
+                       }
+                       if (Host == null) {
+                               throw new InvalidOperationException(); // can only be called within an ASP.NET AppDomain
+                       }
+
+                       QueueBackgroundWorkItemInternal(workItem);
+               }
+
+               static void QueueBackgroundWorkItemInternal(Func<CancellationToken, Task> workItem) {
+                       Debug.Assert(workItem != null);
+
+                       BackgroundWorkScheduler scheduler = Volatile.Read(ref _backgroundWorkScheduler);
+
+                       // If the scheduler doesn't exist, lazily create it, but only allow one instance to ever be published to the backing field
+                       if (scheduler == null) {
+                               BackgroundWorkScheduler newlyCreatedScheduler = new BackgroundWorkScheduler(UnregisterObject, WriteUnhandledException);
+                               scheduler = Interlocked.CompareExchange(ref _backgroundWorkScheduler, newlyCreatedScheduler, null) ?? newlyCreatedScheduler;
+                               if (scheduler == newlyCreatedScheduler) {
+                                       RegisterObject(scheduler); // Only call RegisterObject if we just created the "winning" one
+                               }
+                       }
+
+                       scheduler.ScheduleWorkItem(workItem);
+               }
+
+               static void WriteUnhandledException (AppDomain appDomain, Exception exception)
+               {
+                       Console.Error.WriteLine ("Error in background work item: " + exception);
+               }
        }
 }
 
index 46f3627f416fa5f5342ba4ef05c35b8a56e65ba1..742d1b4eb09779e63e3f27c258dfc3d9e1847d89 100644 (file)
@@ -290,6 +290,7 @@ System.Web.Hosting/AppManagerAppDomainFactory.cs
 System.Web.Hosting/ApplicationInfo.cs
 System.Web.Hosting/ApplicationHost.cs
 System.Web.Hosting/ApplicationManager.cs
+../referencesource/System.Web/Hosting/BackgroundWorkScheduler.cs
 System.Web.Hosting/BareApplicationHost.cs
 System.Web.Hosting/DefaultVirtualDirectory.cs
 System.Web.Hosting/DefaultVirtualFile.cs
@@ -1199,6 +1200,7 @@ System.Web.UI/XhtmlMobileDocType.cs
 System.Web.UI/XhtmlTextWriter.cs
 System.Web.UI/XPathBinder.cs
 System.Web.Util/AltSerialization.cs
+../referencesource/System.Web/Util/CancellationTokenHelper.cs
 System.Web.Util/DataSourceHelper.cs
 System.Web.Util/DataSourceResolver.cs
 System.Web.Util/FileUtils.cs
index 8efb18cc93ef6d734bdc7f42df4760900c2b96e7..073bb3c9c25def79057bdda3d85bcef83a8fbd04 100644 (file)
@@ -16,7 +16,8 @@ endif
 
 RESX_RESOURCE_STRING = \
        ../../../external/corefx/src/System.Collections.Concurrent/src/Resources/Strings.resx \
-       ../../../external/corefx/src/System.Collections/src/Resources/Strings.resx
+       ../../../external/corefx/src/System.Collections/src/Resources/Strings.resx \
+       ../../../external/corefx/src/System.Buffers/src/Resources/Strings.resx
 
 TEST_RESOURCES = \
        Test/System/test-uri-props.txt \
index 5b3aae1a70d010f91cc05a96296c9c7e8ccb2f56..00c77a9f0430497a4641fb359c8ef7f33dc26810 100644 (file)
@@ -42,7 +42,7 @@ namespace Mono.Net.Security
                {
 #if MONOTOUCH
                        is_macosx = true;
-#elif MONODROID
+#elif MONODROID || ORBIS
                        is_macosx = false;
 #else
                        is_macosx = Environment.OSVersion.Platform != PlatformID.Win32NT && System.IO.File.Exists (OSX509Certificates.SecurityLibrary);
@@ -156,6 +156,7 @@ namespace Mono.Net.Security
                        }
 #else
                        if (is_macosx) {
+#if !ORBIS
                                // Attempt to use OSX certificates
                                // Ideally we should return the SecTrustResult
                                OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
@@ -180,6 +181,9 @@ namespace Mono.Net.Security
                                        status11 = (int)trustResult;
                                        errors |= SslPolicyErrors.RemoteCertificateChainErrors;
                                }
+#else
+                               throw new PlatformNotSupportedException ();
+#endif
                        } else {
                                result = BuildX509Chain (certs, chain, ref errors, ref status11);
                        }
index 0b1baaa7af7b8a8f3c1fb15b9531bc2160c57e96..edcca181b511c24a912537c7561393c677bd7bce 100644 (file)
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\Collections\Generic\LargeArrayBuilder.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\CSharpHelpers.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\IO\TempFileCollection.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\Logging\NetEventSource.Common.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\SecurityProtocol.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\UriScheme.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\WebSockets\ManagedWebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\WebSockets\WebSocketValidate.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\StringExtensions.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\ArrayPool.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\ArrayPoolEventSource.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\DefaultArrayPool.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\DefaultArrayPoolBucket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\Utilities.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpCodeGenerator.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpCodeProvider.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpMemberAttributeConverter.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\CompressionLevel.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\CompressionMode.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\GZipStream.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.HttpListener\src\System\Net\WebSockets\HttpListenerWebSocketContext.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\ClientWebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\ClientWebSocketOptions.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\WebSocketHandle.Managed.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketCloseStatus.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketContext.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketError.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketException.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketMessageType.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketReceiveResult.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketState.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Runtime.Extensions\src\System\CodeDom\Compiler\IndentedTextWriter.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Runtime\src\System\Collections\Generic\ISet.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Security.Cryptography.X509Certificates\src\System\Security\Cryptography\X509Certificates\OpenFlags.cs" />\r
     <Compile Include="System.Net.Sockets\SocketReceiveFromResult.cs" />\r
     <Compile Include="System.Net.Sockets\SocketReceiveMessageFromResult.cs" />\r
     <Compile Include="System.Net.Sockets\SocketTaskExtensions.cs" />\r
-    <Compile Include="System.Net.WebSockets\ClientWebSocket.cs" />\r
-    <Compile Include="System.Net.WebSockets\ClientWebSocketOptions.cs" />\r
-    <Compile Include="System.Net.WebSockets\HttpListenerWebSocketContext.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocket.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketCloseStatus.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketContext.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketError.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketException.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketMessageType.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketReceiveResult.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketState.cs" />\r
     <Compile Include="System.Net\AuthenticationManager.cs" />\r
     <Compile Include="System.Net\BasicClient.cs" />\r
     <Compile Include="System.Net\BindIPEndPoint.cs" />\r
index 50577efc812c8c3943098149dc34bfa16b9bbfb4..567edc59d33490f17d68235e62190cd9e8e28e4e 100644 (file)
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\Collections\Generic\LargeArrayBuilder.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\CSharpHelpers.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\IO\TempFileCollection.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\Logging\NetEventSource.Common.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\SecurityProtocol.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\UriScheme.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\WebSockets\ManagedWebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\WebSockets\WebSocketValidate.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\StringExtensions.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\ArrayPool.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\ArrayPoolEventSource.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\DefaultArrayPool.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\DefaultArrayPoolBucket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\Utilities.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpCodeGenerator.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpCodeProvider.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpMemberAttributeConverter.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\CompressionLevel.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\CompressionMode.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\GZipStream.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.HttpListener\src\System\Net\WebSockets\HttpListenerWebSocketContext.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\ClientWebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\ClientWebSocketOptions.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\WebSocketHandle.Managed.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketCloseStatus.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketContext.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketError.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketException.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketMessageType.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketReceiveResult.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketState.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Runtime.Extensions\src\System\CodeDom\Compiler\IndentedTextWriter.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Runtime\src\System\Collections\Generic\ISet.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Security.Cryptography.X509Certificates\src\System\Security\Cryptography\X509Certificates\OpenFlags.cs" />\r
     <Compile Include="System.Net.Sockets\SocketReceiveFromResult.cs" />\r
     <Compile Include="System.Net.Sockets\SocketReceiveMessageFromResult.cs" />\r
     <Compile Include="System.Net.Sockets\SocketTaskExtensions.cs" />\r
-    <Compile Include="System.Net.WebSockets\ClientWebSocket.cs" />\r
-    <Compile Include="System.Net.WebSockets\ClientWebSocketOptions.cs" />\r
-    <Compile Include="System.Net.WebSockets\HttpListenerWebSocketContext.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocket.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketCloseStatus.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketContext.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketError.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketException.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketMessageType.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketReceiveResult.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketState.cs" />\r
     <Compile Include="System.Net\AuthenticationManager.cs" />\r
     <Compile Include="System.Net\BasicClient.cs" />\r
     <Compile Include="System.Net\BindIPEndPoint.cs" />\r
index ddaafd283905def3aa06f11aeee924e8e7a7aaf2..cae16569acb24057e017a88541f7f4a96e533c13 100644 (file)
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\Collections\Generic\LargeArrayBuilder.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\CSharpHelpers.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\Common\src\System\IO\TempFileCollection.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\Logging\NetEventSource.Common.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\SecurityProtocol.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\UriScheme.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\WebSockets\ManagedWebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\Net\WebSockets\WebSocketValidate.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\Common\src\System\StringExtensions.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\ArrayPool.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\ArrayPoolEventSource.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\DefaultArrayPool.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\DefaultArrayPoolBucket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Buffers\src\System\Buffers\Utilities.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpCodeGenerator.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpCodeProvider.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.CodeDom\src\Microsoft\CSharp\CSharpMemberAttributeConverter.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\CompressionLevel.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\CompressionMode.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.IO.Compression\src\System\IO\Compression\GZipStream.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.HttpListener\src\System\Net\WebSockets\HttpListenerWebSocketContext.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\ClientWebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\ClientWebSocketOptions.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets.Client\src\System\Net\WebSockets\WebSocketHandle.Managed.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocket.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketCloseStatus.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketContext.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketError.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketException.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketMessageType.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketReceiveResult.cs" />\r
+    <Compile Include="..\..\..\external\corefx\src\System.Net.WebSockets\src\System\Net\WebSockets\WebSocketState.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Runtime.Extensions\src\System\CodeDom\Compiler\IndentedTextWriter.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Runtime\src\System\Collections\Generic\ISet.cs" />\r
     <Compile Include="..\..\..\external\corefx\src\System.Security.Cryptography.X509Certificates\src\System\Security\Cryptography\X509Certificates\OpenFlags.cs" />\r
     <Compile Include="System.Net.Sockets\SocketReceiveFromResult.cs" />\r
     <Compile Include="System.Net.Sockets\SocketReceiveMessageFromResult.cs" />\r
     <Compile Include="System.Net.Sockets\SocketTaskExtensions.cs" />\r
-    <Compile Include="System.Net.WebSockets\ClientWebSocket.cs" />\r
-    <Compile Include="System.Net.WebSockets\ClientWebSocketOptions.cs" />\r
-    <Compile Include="System.Net.WebSockets\HttpListenerWebSocketContext.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocket.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketCloseStatus.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketContext.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketError.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketException.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketMessageType.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketReceiveResult.cs" />\r
-    <Compile Include="System.Net.WebSockets\WebSocketState.cs" />\r
     <Compile Include="System.Net\AuthenticationManager.cs" />\r
     <Compile Include="System.Net\BasicClient.cs" />\r
     <Compile Include="System.Net\BindIPEndPoint.cs" />\r
index 9d8dd61eb2415641247d742c0cc3f77c7130ed3f..8249d786c2e1a5d68f72e0981878d3c0aec30e80 100644 (file)
@@ -486,6 +486,7 @@ namespace System.IO.Compression
                const string LIBNAME = "MonoPosixHelper";
 #endif
 
+#if !ORBIS
                [DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
                static extern IntPtr CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data);
 
@@ -500,6 +501,33 @@ namespace System.IO.Compression
 
                [DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
                static extern int WriteZStream (IntPtr stream, IntPtr buffer, int length);
+#else
+               static IntPtr CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+               static int CloseZStream (IntPtr stream)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+               static int Flush (IntPtr stream)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+               static int ReadZStream (IntPtr stream, IntPtr buffer, int length)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+               static int WriteZStream (IntPtr stream, IntPtr buffer, int length)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+#endif
+
        }
 }
 
index 0048b72c986f0c52287686cc5fc1a42eb17f7c8d..92bd3ffb363ed22d41fcae547bdece2f68ef9632 100644 (file)
@@ -42,8 +42,15 @@ namespace System.Net.NetworkInformation {
                [DllImport ("libc")]
                static extern int gethostname ([MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] name, int len);
 
+#if !ORBIS
                [DllImport ("libc")]
                static extern int getdomainname ([MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] name, int len);
+#else
+               static int getdomainname ([MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] name, int len)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+#endif
 
                public override string DhcpScopeName {
                        get { return String.Empty; }
index 9b6b1e5df94842d45a14909a04e72e1d87449881..8304ac82b4fdb1615c3b6ff48a38d25b0b91d389 100644 (file)
@@ -101,7 +101,7 @@ namespace System.Net.NetworkInformation {
 
                static void MaybeCreate ()
                {
-#if MONOTOUCH_WATCH
+#if MONOTOUCH_WATCH || ORBIS
                        throw new PlatformNotSupportedException ("NetworkInformation.NetworkChange is not supported on the current platform.");
 #else
                        if (networkChange != null)
@@ -126,7 +126,7 @@ namespace System.Net.NetworkInformation {
                }
        }
 
-#if !MONOTOUCH_WATCH
+#if !MONOTOUCH_WATCH && !ORBIS
        internal sealed class MacNetworkChange : INetworkChange
        {
                const string DL_LIB = "/usr/lib/libSystem.dylib";
@@ -322,7 +322,7 @@ namespace System.Net.NetworkInformation {
        }
 #endif // !MONOTOUCH_WATCH
 
-#if !NETWORK_CHANGE_STANDALONE && !MONOTOUCH
+#if !NETWORK_CHANGE_STANDALONE && !MONOTOUCH && !ORBIS
 
        internal sealed class LinuxNetworkChange : INetworkChange {
                [Flags]
index 0967c80485dd8988f9c0936f0017bf3981fa2446..a97bcc8049c8a789e509a37c3f25efcf8e28a993 100644 (file)
@@ -82,6 +82,22 @@ namespace System.Net.NetworkInformation {
        {
                internal abstract class UnixNetworkInterfaceAPI : NetworkInterfaceFactory
                {
+#if ORBIS
+                       public static int if_nametoindex(string ifname)
+                       {
+                               throw new PlatformNotSupportedException ();
+                       }
+
+                       protected static int getifaddrs (out IntPtr ifap)
+                       {
+                               throw new PlatformNotSupportedException ();
+                       }
+
+                       protected static void freeifaddrs (IntPtr ifap)
+                       {
+                               throw new PlatformNotSupportedException ();
+                       }
+#else
                        [DllImport("libc")]
                        public static extern int if_nametoindex(string ifname);
 
@@ -90,6 +106,7 @@ namespace System.Net.NetworkInformation {
 
                        [DllImport ("libc")]
                        protected static extern void freeifaddrs (IntPtr ifap);
+#endif
                }
 
                class MacOsNetworkInterfaceAPI : UnixNetworkInterfaceAPI
index 90d0e3a59ca568e3ed6340b534f1c9a7237e1f2c..f1f5936be75cab98e14fe59bf44fafafe3cef09f 100644 (file)
@@ -89,7 +89,7 @@ namespace System.Net.NetworkInformation {
                
                public event PingCompletedEventHandler PingCompleted;
 
-#if !MONOTOUCH
+#if !MONOTOUCH && !ORBIS
                static Ping ()
                {
                        if (Environment.OSVersion.Platform == PlatformID.Unix) {
@@ -122,7 +122,7 @@ namespace System.Net.NetworkInformation {
                        identifier = (ushort)(randomIdentifier [0] + (randomIdentifier [1] << 8));
                }
 
-#if !MONOTOUCH
+#if !MONOTOUCH && !ORBIS
                [DllImport ("libc", EntryPoint="capget")]
                static extern int capget (ref cap_user_header_t header, ref cap_user_data_t data);
 
index 264eb7a50f7e63acb55114459d7ec235dd94fee8..8d6e9ddbc5ea696dbf12c83f37f4a29bce44a421 100644 (file)
@@ -40,7 +40,6 @@ using CipherAlgorithmType = System.Security.Authentication.CipherAlgorithmType;
 using HashAlgorithmType = System.Security.Authentication.HashAlgorithmType;
 using ExchangeAlgorithmType = System.Security.Authentication.ExchangeAlgorithmType;
 
-using System;
 using System.IO;
 using System.Net;
 using System.Net.Security;
@@ -49,7 +48,6 @@ using System.Security.Cryptography.X509Certificates;
 using System.Security.Permissions;
 using System.Security.Principal;
 using System.Security.Cryptography;
-
 using System.Threading.Tasks;
 
 using MNS = Mono.Net.Security;
@@ -402,10 +400,81 @@ namespace System.Net.Security
        }
 }
 #else // !SECURITY_DEP
+
+using System.IO;
+using System.Threading.Tasks;
+
 namespace System.Net.Security
 {
-       public class SslStream
+       public class SslStream : Stream
        {
+               public SslStream (object innerStream)
+               {
+               }
+
+               public override bool CanRead {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public override bool CanSeek {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public override bool CanWrite {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public override long Length {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public override long Position {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public override void Flush ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override int Read (System.Byte [] buffer, int offset, int count)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override long Seek (long offset, SeekOrigin origin)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override void SetLength (long value)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override void Write (System.Byte [] buffer, int offset, int count)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public virtual Task AuthenticateAsClientAsync (string targetHost, object clientCertificates, object enabledSslProtocols, bool checkCertificateRevocation)
+               {
+                       throw new NotImplementedException ();
+               }
        }
 }
 #endif
diff --git a/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs b/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs
deleted file mode 100644 (file)
index dba02f2..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-//
-// ClientWebSocket.cs
-//
-// Authors:
-//       Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Lightly inspired from WebSocket4Net distributed under the Apache License 2.0
-//
-// 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.Net;
-using System.Net.Sockets;
-using System.Security.Principal;
-using System.Security.Cryptography.X509Certificates;
-using System.Runtime.CompilerServices;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Globalization;
-using System.Text;
-using System.Security.Cryptography;
-
-namespace System.Net.WebSockets
-{
-       public class ClientWebSocket : WebSocket, IDisposable
-       {
-               const string Magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
-               const string VersionTag = "13";
-
-               ClientWebSocketOptions options;
-               WebSocketState state;
-               string subProtocol;
-
-               HttpWebRequest req;
-               WebConnection connection;
-               Socket underlyingSocket;
-
-               Random random = new Random ();
-
-               const int HeaderMaxLength = 14;
-               byte[] headerBuffer;
-               byte[] sendBuffer;
-               long remaining;
-               WebSocketMessageType currentMessageType;
-
-               public ClientWebSocket ()
-               {
-                       options = new ClientWebSocketOptions ();
-                       state = WebSocketState.None;
-                       headerBuffer = new byte[HeaderMaxLength];
-               }
-
-               public override void Dispose ()
-               {
-                       if (connection != null)
-                               connection.Close (false);
-               }
-
-               [MonoTODO]
-               public override void Abort ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public ClientWebSocketOptions Options {
-                       get {
-                               return options;
-                       }
-               }
-
-               public override WebSocketState State {
-                       get {
-                               return state;
-                       }
-               }
-
-               public override WebSocketCloseStatus? CloseStatus {
-                       get {
-                               if (state != WebSocketState.Closed)
-                                       return (WebSocketCloseStatus?)null;
-                               return WebSocketCloseStatus.Empty;
-                       }
-               }
-
-               public override string CloseStatusDescription {
-                       get {
-                               return null;
-                       }
-               }
-
-               public override string SubProtocol {
-                       get {
-                               return subProtocol;
-                       }
-               }
-
-               public async Task ConnectAsync (Uri uri, CancellationToken cancellationToken)
-               {
-                       state = WebSocketState.Connecting;
-                       var httpUri = new UriBuilder (uri);
-                       if (uri.Scheme == "wss")
-                               httpUri.Scheme = "https";
-                       else
-                               httpUri.Scheme = "http";
-                       req = (HttpWebRequest)WebRequest.Create (httpUri.Uri);
-                       req.ReuseConnection = true;
-                       if (options.Cookies != null)
-                               req.CookieContainer = options.Cookies;
-
-                       if (options.CustomRequestHeaders.Count > 0) {
-                               foreach (var header in options.CustomRequestHeaders)
-                                       req.Headers[header.Key] = header.Value;
-                       }
-
-                       var secKey = Convert.ToBase64String (Encoding.ASCII.GetBytes (Guid.NewGuid ().ToString ().Substring (0, 16)));
-                       string expectedAccept = Convert.ToBase64String (SHA1.Create ().ComputeHash (Encoding.ASCII.GetBytes (secKey + Magic)));
-
-                       req.Headers["Upgrade"] = "WebSocket";
-                       req.Headers["Sec-WebSocket-Version"] = VersionTag;
-                       req.Headers["Sec-WebSocket-Key"] = secKey;
-                       req.Headers["Sec-WebSocket-Origin"] = uri.Host;
-                       if (options.SubProtocols.Count > 0)
-                               req.Headers["Sec-WebSocket-Protocol"] = string.Join (",", options.SubProtocols);
-
-                       if (options.Credentials != null)
-                               req.Credentials = options.Credentials;
-                       if (options.ClientCertificates != null)
-                               req.ClientCertificates = options.ClientCertificates;
-                       if (options.Proxy != null)
-                               req.Proxy = options.Proxy;
-                       req.UseDefaultCredentials = options.UseDefaultCredentials;
-                       req.Connection = "Upgrade";
-
-                       HttpWebResponse resp = null;
-                       try {
-                               resp = (HttpWebResponse)(await req.GetResponseAsync ().ConfigureAwait (false));
-                       } catch (Exception e) {
-                               throw new WebSocketException (WebSocketError.Success, e);
-                       }
-
-                       connection = req.StoredConnection;
-                       underlyingSocket = connection.socket;
-
-                       if (resp.StatusCode != HttpStatusCode.SwitchingProtocols)
-                               throw new WebSocketException ("The server returned status code '" + (int)resp.StatusCode + "' when status code '101' was expected");
-                       if (!string.Equals (resp.Headers["Upgrade"], "WebSocket", StringComparison.OrdinalIgnoreCase)
-                               || !string.Equals (resp.Headers["Connection"], "Upgrade", StringComparison.OrdinalIgnoreCase)
-                               || !string.Equals (resp.Headers["Sec-WebSocket-Accept"], expectedAccept))
-                               throw new WebSocketException ("HTTP header error during handshake");
-                       if (resp.Headers["Sec-WebSocket-Protocol"] != null) {
-                               if (!options.SubProtocols.Contains (resp.Headers["Sec-WebSocket-Protocol"]))
-                                       throw new WebSocketException (WebSocketError.UnsupportedProtocol);
-                               subProtocol = resp.Headers["Sec-WebSocket-Protocol"];
-                       }
-
-                       state = WebSocketState.Open;
-               }
-
-               public override Task SendAsync (ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
-               {
-                       EnsureWebSocketConnected ();
-                       ValidateArraySegment (buffer);
-                       if (connection == null)
-                               throw new WebSocketException (WebSocketError.Faulted);
-                       var count = Math.Max (options.SendBufferSize, buffer.Count) + HeaderMaxLength;
-                       if (sendBuffer == null || sendBuffer.Length != count)
-                               sendBuffer = new byte[count];
-                       return Task.Run (() => {
-                               EnsureWebSocketState (WebSocketState.Open, WebSocketState.CloseReceived);
-                               var maskOffset = WriteHeader (messageType, buffer, endOfMessage);
-
-                               if (buffer.Count > 0)
-                                       MaskData (buffer, maskOffset);
-                               //underlyingSocket.Send (headerBuffer, 0, maskOffset + 4, SocketFlags.None);
-                               var headerLength = maskOffset + 4;
-                               Array.Copy (headerBuffer, sendBuffer, headerLength);
-                               underlyingSocket.Send (sendBuffer, 0, buffer.Count + headerLength, SocketFlags.None);
-                       });
-               }
-               
-               const int messageTypeContinuation = 0;
-               const int messageTypeText = 1;
-               const int messageTypeBinary = 2;
-               const int messageTypeClose = 8;
-
-               WebSocketMessageType WireToMessageType (byte msgType)
-               {
-                       
-                       if (msgType == messageTypeContinuation)
-                               return currentMessageType;
-                       if (msgType == messageTypeText)
-                               return WebSocketMessageType.Text;
-                       if (msgType == messageTypeBinary)
-                               return WebSocketMessageType.Binary;
-                       return WebSocketMessageType.Close;
-               }
-
-               static byte MessageTypeToWire (WebSocketMessageType type)
-               {
-                       if (type == WebSocketMessageType.Text)
-                               return messageTypeText;
-                       if (type == WebSocketMessageType.Binary)
-                               return messageTypeBinary;
-                       return messageTypeClose;
-               }
-               
-               public override Task<WebSocketReceiveResult> ReceiveAsync (ArraySegment<byte> buffer, CancellationToken cancellationToken)
-               {
-                       EnsureWebSocketConnected ();
-                       ValidateArraySegment (buffer);
-                       return Task.Run (() => {
-                               EnsureWebSocketState (WebSocketState.Open, WebSocketState.CloseSent);
-
-                               bool isLast;
-                               long length;
-
-                               if (remaining == 0) {
-                                       // First read the two first bytes to know what we are doing next
-                                       connection.Read (req, headerBuffer, 0, 2);
-                                       isLast = (headerBuffer[0] >> 7) > 0;
-                                       var isMasked = (headerBuffer[1] >> 7) > 0;
-                                       int mask = 0;
-                                       currentMessageType = WireToMessageType ((byte)(headerBuffer[0] & 0xF));
-                                       length = headerBuffer[1] & 0x7F;
-                                       int offset = 0;
-                                       if (length == 126) {
-                                               offset = 2;
-                                               connection.Read (req, headerBuffer, 2, offset);
-                                       length = (headerBuffer[2] << 8) | headerBuffer[3];
-                                       } else if (length == 127) {
-                                               offset = 8;
-                                               connection.Read (req, headerBuffer, 2, offset);
-                                               length = 0;
-                                               for (int i = 2; i <= 9; i++)
-                                                       length = (length << 8) | headerBuffer[i];
-                                       }
-
-                                       if (isMasked) {
-                                               connection.Read (req, headerBuffer, 2 + offset, 4);
-                                               for (int i = 0; i < 4; i++) {
-                                                       var pos = i + offset + 2;
-                                                       mask = (mask << 8) | headerBuffer[pos];
-                                               }
-                                       }
-                               } else {
-                                       isLast = (headerBuffer[0] >> 7) > 0;
-                                       currentMessageType = WireToMessageType ((byte)(headerBuffer[0] & 0xF));
-                                       length = remaining;
-                               }
-
-                               if (currentMessageType == WebSocketMessageType.Close) {
-                                       state = WebSocketState.Closed;
-                                       var tmpBuffer = new byte[length];
-                                       connection.Read (req, tmpBuffer, 0, tmpBuffer.Length);
-                                       var closeStatus = (WebSocketCloseStatus)(tmpBuffer[0] << 8 | tmpBuffer[1]);
-                                       var closeDesc = tmpBuffer.Length > 2 ? Encoding.UTF8.GetString (tmpBuffer, 2, tmpBuffer.Length - 2) : string.Empty;
-                                       return new WebSocketReceiveResult ((int)length, currentMessageType, isLast, closeStatus, closeDesc);
-                               } else {
-                                       var readLength = (int)(buffer.Count < length ? buffer.Count : length);
-                                       connection.Read (req, buffer.Array, buffer.Offset, readLength);
-                                       remaining = length - readLength;
-
-                                       return new WebSocketReceiveResult ((int)readLength, currentMessageType, isLast && remaining == 0);
-                               }
-                       });
-               }
-
-               // The damn difference between those two methods is that CloseAsync will wait for server acknowledgement before completing
-               // while CloseOutputAsync will send the close packet and simply complete.
-
-               public async override Task CloseAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
-               {
-                       EnsureWebSocketConnected ();
-                       await SendCloseFrame (closeStatus, statusDescription, cancellationToken).ConfigureAwait (false);
-                       state = WebSocketState.CloseSent;
-                       // TODO: figure what's exceptions are thrown if the server returns something faulty here
-                       await ReceiveAsync (new ArraySegment<byte> (new byte[0]), cancellationToken).ConfigureAwait (false);
-                       state = WebSocketState.Closed;
-               }
-
-               public async override Task CloseOutputAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
-               {
-                       EnsureWebSocketConnected ();
-                       await SendCloseFrame (closeStatus, statusDescription, cancellationToken).ConfigureAwait (false);
-                       state = WebSocketState.CloseSent;
-               }
-
-               async Task SendCloseFrame (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
-               {
-                       var statusDescBuffer = string.IsNullOrEmpty (statusDescription) ? new byte[2] : new byte[2 + Encoding.UTF8.GetByteCount (statusDescription)];
-                       statusDescBuffer[0] = (byte)(((ushort)closeStatus) >> 8);
-                       statusDescBuffer[1] = (byte)(((ushort)closeStatus) & 0xFF);
-                       if (!string.IsNullOrEmpty (statusDescription))
-                               Encoding.UTF8.GetBytes (statusDescription, 0, statusDescription.Length, statusDescBuffer, 2);
-                       await SendAsync (new ArraySegment<byte> (statusDescBuffer), WebSocketMessageType.Close, true, cancellationToken).ConfigureAwait (false);
-               }
-
-               int WriteHeader (WebSocketMessageType type, ArraySegment<byte> buffer, bool endOfMessage)
-               {
-                       var opCode = MessageTypeToWire (type);
-                       var length = buffer.Count;
-
-                       headerBuffer[0] = (byte)(opCode | (endOfMessage ? 0x80 : 0));
-                       if (length < 126) {
-                               headerBuffer[1] = (byte)length;
-                       } else if (length <= ushort.MaxValue) {
-                               headerBuffer[1] = (byte)126;
-                               headerBuffer[2] = (byte)(length / 256);
-                               headerBuffer[3] = (byte)(length % 256);
-                       } else {
-                               headerBuffer[1] = (byte)127;
-
-                               int left = length;
-                               int unit = 256;
-
-                               for (int i = 9; i > 1; i--) {
-                                       headerBuffer[i] = (byte)(left % unit);
-                                       left = left / unit;
-                               }
-                       }
-
-                       var l = Math.Max (0, headerBuffer[1] - 125);
-                       var maskOffset = 2 + l * l * 2;
-                       GenerateMask (headerBuffer, maskOffset);
-
-                       // Since we are client only, we always mask the payload
-                       headerBuffer[1] |= 0x80;
-
-                       return maskOffset;
-               }
-
-               void GenerateMask (byte[] mask, int offset)
-               {
-                       mask[offset + 0] = (byte)random.Next (0, 255);
-                       mask[offset + 1] = (byte)random.Next (0, 255);
-                       mask[offset + 2] = (byte)random.Next (0, 255);
-                       mask[offset + 3] = (byte)random.Next (0, 255);
-               }
-
-               void MaskData (ArraySegment<byte> buffer, int maskOffset)
-               {
-                       var sendBufferOffset = maskOffset + 4;
-                       for (var i = 0; i < buffer.Count; i++)
-                               sendBuffer[i + sendBufferOffset] = (byte)(buffer.Array[buffer.Offset + i] ^ headerBuffer[maskOffset + (i % 4)]);
-               }
-
-               void EnsureWebSocketConnected ()
-               {
-                       if (state < WebSocketState.Open)
-                               throw new InvalidOperationException ("The WebSocket is not connected");
-               }
-
-               void EnsureWebSocketState (params WebSocketState[] validStates)
-               {
-                       foreach (var validState in validStates)
-                               if (state == validState)
-                                       return;
-                       throw new WebSocketException ("The WebSocket is in an invalid state ('" + state + "') for this operation. Valid states are: " + string.Join (", ", validStates));
-               }
-
-               void ValidateArraySegment (ArraySegment<byte> segment)
-               {
-                       if (segment.Array == null)
-                               throw new ArgumentNullException ("buffer.Array");
-                       if (segment.Offset < 0)
-                               throw new ArgumentOutOfRangeException ("buffer.Offset");
-                       if (segment.Offset + segment.Count > segment.Array.Length)
-                               throw new ArgumentOutOfRangeException ("buffer.Count");
-               }
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/ClientWebSocket.platformnotsupported.cs b/mcs/class/System/System.Net.WebSockets/ClientWebSocket.platformnotsupported.cs
deleted file mode 100644 (file)
index 324ae42..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// ClientWebSocket.cs
-//
-// Author:
-//     Rolf Bjarne Kvinge <rolf@xamarin.com>
-//
-// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.WebSockets
-{
-       public class ClientWebSocket : WebSocket, IDisposable
-       {
-               const string EXCEPTION_MESSAGE = "System.Net.WebSockets.ClientWebSocket is not supported on the current platform.";
-
-               public ClientWebSocket ()
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public override void Dispose ()
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public override void Abort ()
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public ClientWebSocketOptions Options {
-                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
-               }
-
-               public override WebSocketState State {
-                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
-               }
-
-               public override WebSocketCloseStatus? CloseStatus {
-                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
-               }
-
-               public override string CloseStatusDescription {
-                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
-               }
-
-               public override string SubProtocol {
-                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
-               }
-
-               public Task ConnectAsync (Uri uri, CancellationToken cancellationToken)
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public override Task SendAsync (ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public override Task<WebSocketReceiveResult> ReceiveAsync (ArraySegment<byte> buffer, CancellationToken cancellationToken)
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public override Task CloseAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-
-               public override Task CloseOutputAsync (WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
-               {
-                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
-               }
-       }
-}
diff --git a/mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs b/mcs/class/System/System.Net.WebSockets/ClientWebSocketOptions.cs
deleted file mode 100644 (file)
index 66b884a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// ClientWebSocketOptions.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Net;
-using System.Security.Principal;
-using System.Security.Cryptography.X509Certificates;
-using System.Runtime.CompilerServices;
-using System.Collections.Generic;
-
-namespace System.Net.WebSockets
-{
-       public sealed class ClientWebSocketOptions
-       {
-               List<string> subprotocols = new List<string> ();
-               Dictionary<string, string> customRequestHeaders = new Dictionary<string, string> ();
-
-               public X509CertificateCollection ClientCertificates { get; set; }
-
-               public CookieContainer Cookies { get; set; }
-
-               public ICredentials Credentials { get; set; }
-
-               public TimeSpan KeepAliveInterval { get; set; }
-
-               public IWebProxy Proxy { get; set; }
-
-               public bool UseDefaultCredentials { get; set; }
-
-               internal IList<string> SubProtocols {
-                       get {
-                               return subprotocols.AsReadOnly ();
-                       }
-               }
-
-               internal Dictionary<string, string> CustomRequestHeaders {
-                       get {
-                               return customRequestHeaders;
-                       }
-               }
-
-               internal int ReceiveBufferSize {
-                       get;
-                       private set;
-               }
-
-               internal ArraySegment<byte> CustomReceiveBuffer {
-                       get;
-                       private set;
-               }
-
-               internal int SendBufferSize {
-                       get;
-                       private set;
-               }
-
-               public void AddSubProtocol (string subProtocol)
-               {
-                       subprotocols.Add (subProtocol);
-               }
-
-               public void SetBuffer (int receiveBufferSize, int sendBufferSize)
-               {
-                       SetBuffer (receiveBufferSize, sendBufferSize, new ArraySegment<byte> ());
-               }
-
-               public void SetBuffer (int receiveBufferSize, int sendBufferSize, ArraySegment<byte> buffer)
-               {
-                       ReceiveBufferSize = receiveBufferSize;
-                       SendBufferSize = sendBufferSize;
-                       CustomReceiveBuffer = buffer;
-               }
-
-               public void SetRequestHeader (string headerName, string headerValue)
-               {
-                       customRequestHeaders[headerName] = headerValue;
-               }
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/HttpListenerWebSocketContext.cs b/mcs/class/System/System.Net.WebSockets/HttpListenerWebSocketContext.cs
deleted file mode 100644 (file)
index d37eb24..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// HttpListenerWebSocketContext.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-#if SECURITY_DEP
-
-using System;
-using System.Net;
-using System.Collections.Specialized;
-using System.Collections.Generic;
-using System.Security.Principal;
-using System.Security.Cryptography.X509Certificates;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public class HttpListenerWebSocketContext : WebSocketContext
-       {
-               [MonoTODO]
-               public override CookieCollection CookieCollection {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override NameValueCollection Headers {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override bool IsAuthenticated {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override bool IsLocal {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override bool IsSecureConnection {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override string Origin {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override Uri RequestUri {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override string SecWebSocketKey {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override IEnumerable<string> SecWebSocketProtocols {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override string SecWebSocketVersion {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override IPrincipal User {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               [MonoTODO]
-               public override WebSocket WebSocket {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-       }
-}
-#endif
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocket.cs b/mcs/class/System/System.Net.WebSockets/WebSocket.cs
deleted file mode 100644 (file)
index 4d0c9b2..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-//
-// WebSocket.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public abstract class WebSocket : IDisposable
-       {
-               protected WebSocket ()
-               {
-                       
-               }
-
-               public abstract Nullable<WebSocketCloseStatus> CloseStatus { get; }
-               public abstract string CloseStatusDescription { get; }
-               public abstract WebSocketState State { get; }
-               public abstract string SubProtocol { get; }
-
-               [MonoTODO]
-               public static TimeSpan DefaultKeepAliveInterval {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
-               public abstract void Abort ();
-               
-               public abstract Task CloseAsync (WebSocketCloseStatus closeStatus,
-                                                string statusDescription,
-                                                CancellationToken cancellationToken);
-
-               public abstract Task CloseOutputAsync (WebSocketCloseStatus closeStatus,
-                                                      string statusDescription,
-                                                      CancellationToken cancellationToken);
-
-               public abstract Task<WebSocketReceiveResult> ReceiveAsync (ArraySegment<byte> buffer,
-                                                                          CancellationToken cancellationToken);
-
-               public abstract Task SendAsync (ArraySegment<byte> buffer,
-                                               WebSocketMessageType messageType,
-                                               bool endOfMessage,
-                                               CancellationToken cancellationToken);
-
-               [MonoTODO]
-               public static ArraySegment<byte> CreateClientBuffer (int receiveBufferSize, int sendBufferSize)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public static WebSocket CreateClientWebSocket (Stream innerStream,
-                                                              string subProtocol,
-                                                              int receiveBufferSize,
-                                                              int sendBufferSize,
-                                                              TimeSpan keepAliveInterval,
-                                                              bool useZeroMaskingKey,
-                                                              ArraySegment<byte> internalBuffer)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public static ArraySegment<byte> CreateServerBuffer (int receiveBufferSize)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [ObsoleteAttribute, MonoTODO]
-               public static bool IsApplicationTargeting45 ()
-               {
-                       return true;
-               }
-
-               [MonoTODO]
-               public static void RegisterPrefixes ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public abstract void Dispose ();
-
-               protected static bool IsStateTerminal (WebSocketState state)
-               {
-                       return state == WebSocketState.Closed || state == WebSocketState.Aborted;
-               }
-
-               [MonoTODO]
-               protected static void ThrowOnInvalidState (WebSocketState state, params WebSocketState[] validStates)
-               {
-                       foreach (var validState in validStates)
-                               if (validState == state)
-                                       return;
-
-                       throw new NotImplementedException ();
-               }
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs b/mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs
deleted file mode 100644 (file)
index d662120..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// WebSocketCloseStatus.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public enum WebSocketCloseStatus
-       {
-               NormalClosure = 1000,
-               EndpointUnavailable = 1001,
-               ProtocolError = 1002,
-               InvalidMessageType = 1003,
-               Empty = 1005,
-               InvalidPayloadData = 1007,
-               PolicyViolation = 1008,
-               MessageTooBig = 1009,
-               MandatoryExtension = 1010,
-               InternalServerError = 1011
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketContext.cs b/mcs/class/System/System.Net.WebSockets/WebSocketContext.cs
deleted file mode 100644 (file)
index 1fd14a9..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// WebSocketContext.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Collections.Specialized;
-using System.Collections.Generic;
-using System.Security.Principal;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public abstract class WebSocketContext
-       {
-               protected WebSocketContext ()
-               {
-                       
-               }
-
-               public abstract CookieCollection CookieCollection { get; }
-
-               public abstract NameValueCollection Headers { get; }
-
-               public abstract bool IsAuthenticated { get; }
-
-               public abstract bool IsLocal { get; }
-
-               public abstract bool IsSecureConnection { get; }
-
-               public abstract string Origin { get; }
-
-               public abstract Uri RequestUri { get; }
-
-               public abstract string SecWebSocketKey { get; }
-
-               public abstract IEnumerable<string> SecWebSocketProtocols { get; }
-
-               public abstract string SecWebSocketVersion { get; }
-
-               public abstract IPrincipal User { get; }
-
-               public abstract WebSocket WebSocket { get; }
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketError.cs b/mcs/class/System/System.Net.WebSockets/WebSocketError.cs
deleted file mode 100644 (file)
index 1218d16..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// WebSocketError.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public enum WebSocketError
-       {
-               Success,
-               InvalidMessageType,
-               Faulted,
-               NativeError,
-               NotAWebSocket,
-               UnsupportedVersion,
-               UnsupportedProtocol,
-               HeaderError,
-               ConnectionClosedPrematurely,
-               InvalidState
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketException.cs b/mcs/class/System/System.Net.WebSockets/WebSocketException.cs
deleted file mode 100644 (file)
index 1c72406..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// WebSocketException.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public sealed class WebSocketException : Win32Exception
-       {
-               const string DefaultMessage = "Generic WebSocket exception";
-
-               public WebSocketException () : this (WebSocketError.Success, -1, DefaultMessage, null)
-               {
-                       
-               }
-
-               public WebSocketException (int nativeError) : this (WebSocketError.Success, nativeError, DefaultMessage, null)
-               {
-                       
-               }
-
-               public WebSocketException (string message) : this (WebSocketError.Success, -1, message, null)
-               {
-                       
-               }
-
-               public WebSocketException (WebSocketError error) : this (error, -1, DefaultMessage, null)
-               {
-               }
-
-               public WebSocketException (int nativeError, Exception innerException) : this (WebSocketError.Success, nativeError, DefaultMessage, innerException)
-               {
-                       
-               }
-
-               public WebSocketException (int nativeError, string message) : this (WebSocketError.Success, nativeError, message, null)
-               {
-                       
-               }
-
-               public WebSocketException (string message, Exception innerException) : this (WebSocketError.Success, -1, message, innerException)
-               {
-                       
-               }
-
-               public WebSocketException (WebSocketError error, Exception innerException) : this (error, -1, DefaultMessage, innerException)
-               {
-
-               }
-
-               public WebSocketException (WebSocketError error, int nativeError) : this (error, nativeError, DefaultMessage, null)
-               {
-               }
-
-               public WebSocketException (WebSocketError error, string message) : this (error, -1, message, null)
-               {
-               }
-
-               public WebSocketException (WebSocketError error, int nativeError, Exception innerException) : this (error, nativeError, DefaultMessage, innerException)
-               {
-               }
-
-               public WebSocketException (WebSocketError error, int nativeError, string message) : this (error, nativeError, message, null)
-               {
-               }
-
-               public WebSocketException (WebSocketError error, string message, Exception innerException) : this (error, -1, message, innerException)
-               {
-               }
-
-               public WebSocketException (WebSocketError error, int nativeError, string message, Exception innerException) : base (message, innerException)
-               {
-                       WebSocketErrorCode = error;
-               }
-
-               public WebSocketError WebSocketErrorCode {
-                       get;
-                       private set;
-               }
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs b/mcs/class/System/System.Net.WebSockets/WebSocketMessageType.cs
deleted file mode 100644 (file)
index 2369548..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// WebSocketMessageType.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public enum WebSocketMessageType
-       {
-               Text = 0,
-               Binary = 1,
-               Close = 2
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs b/mcs/class/System/System.Net.WebSockets/WebSocketReceiveResult.cs
deleted file mode 100644 (file)
index cadf967..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// WebSocketReceiveResult.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Security.Principal;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public class WebSocketReceiveResult
-       {
-               public WebSocketReceiveResult (int count, WebSocketMessageType messageType, bool endOfMessage)
-                    : this (count, messageType, endOfMessage, null, null)
-               {
-               }
-
-               public WebSocketReceiveResult (int count,
-                                              WebSocketMessageType messageType,
-                                              bool endOfMessage,
-                                              WebSocketCloseStatus? closeStatus,
-                                              string closeStatusDescription)
-               {
-                       MessageType = messageType;
-                       CloseStatus = closeStatus;
-                       CloseStatusDescription = closeStatusDescription;
-                       Count = count;
-                       EndOfMessage = endOfMessage;
-               }
-
-               public WebSocketCloseStatus? CloseStatus {
-                       get;
-                       private set;
-               }
-
-               public string CloseStatusDescription {
-                       get;
-                       private set;
-               }
-
-               public int Count {
-                       get;
-                       private set;
-               }
-
-               public bool EndOfMessage {
-                       get;
-                       private set;
-               }
-
-               public WebSocketMessageType MessageType {
-                       get;
-                       private set;
-               }
-       }
-}
-
diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketState.cs b/mcs/class/System/System.Net.WebSockets/WebSocketState.cs
deleted file mode 100644 (file)
index f942dae..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// WebSocketState.cs
-//
-// Authors:
-//    Jérémie Laval <jeremie dot laval at xamarin dot com>
-//
-// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace System.Net.WebSockets
-{
-       public enum WebSocketState
-       {
-               None,
-               Connecting,
-               Open,
-               CloseSent,
-               CloseReceived,
-               Closed,
-               Aborted
-       }
-}
-
index 69b4133226bb0834e49955797829d1a81deb5d43..bd2cdc10b9876881f10ee913c5dac33e576bc6de 100644 (file)
@@ -47,7 +47,7 @@ namespace Mono.Net
                public static extern IntPtr dlopen (string path, int mode);
 
                [DllImport (SystemLibrary)]
-               public static extern IntPtr dlsym (IntPtr handle, string symbol);
+               static extern IntPtr dlsym (IntPtr handle, string symbol);
 
                [DllImport (SystemLibrary)]
                public static extern void dlclose (IntPtr handle);
@@ -1249,8 +1249,8 @@ namespace Mono.Net
                        if (handle == IntPtr.Zero)
                                return;
                        try {
-                               True  = new CFBoolean (CFObject.dlsym (handle, "kCFBooleanTrue"), false);
-                               False = new CFBoolean (CFObject.dlsym (handle, "kCFBooleanFalse"), false);
+                               True  = new CFBoolean (CFObject.GetCFObjectHandle (handle, "kCFBooleanTrue"), false);
+                               False = new CFBoolean (CFObject.GetCFObjectHandle (handle, "kCFBooleanFalse"), false);
                        }
                        finally {
                                CFObject.dlclose (handle);
index 8afd40370cd599aeae22ae1b8ad0b908f5fdc81f..f4214393fc32627110284f0b72ecc62db5c41ae1 100644 (file)
@@ -38,6 +38,14 @@ namespace System {
                        isMacOS = true;
                        checkedOS = true;
                }
+
+#elif ORBIS
+               const bool isFreeBSD = true;
+
+               private static void CheckOS() {
+                       checkedOS = true;
+               }
+
 #else
                static bool isFreeBSD;
 
index b19688cf44cddcd6f2c9ada44d5259c8253967e0..a9a82f94a8d3c3e3fe5b530968e405d66190c845 100644 (file)
@@ -57,7 +57,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
-               [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+               [Category ("NotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void ServerHandshakeReturnCrapStatusCodeTest ()
                {
                        // On purpose, 
@@ -149,7 +149,7 @@ namespace MonoTests.System.Net.WebSockets
                        Assert.AreEqual (WebSocketState.CloseSent, socket.State);
 
                        var resp = socket.ReceiveAsync (new ArraySegment<byte> (new byte[0]), CancellationToken.None).Result;
-                       Assert.AreEqual (WebSocketState.Closed, socket.State);
+                       Assert.AreEqual (WebSocketState.CloseReceived, socket.State);
                        Assert.AreEqual (WebSocketMessageType.Close, resp.MessageType);
                        Assert.AreEqual (WebSocketCloseStatus.NormalClosure, resp.CloseStatus);
                        Assert.AreEqual (string.Empty, resp.CloseStatusDescription);
@@ -211,7 +211,7 @@ namespace MonoTests.System.Net.WebSockets
                                Assert.IsTrue (socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (5000));
                                Assert.IsTrue (socket.ReceiveAsync (new ArraySegment<byte> (new byte[0]), CancellationToken.None).Wait (5000));
                        } catch (AggregateException e) {
-                               AssertWebSocketException (e, WebSocketError.Success);
+                               AssertWebSocketException (e, WebSocketError.InvalidState);
                                return;
                        }
                        Assert.Fail ("Should have thrown");
@@ -226,7 +226,7 @@ namespace MonoTests.System.Net.WebSockets
                                Assert.IsTrue (socket.CloseAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (5000));
                                Assert.IsTrue (socket.SendAsync (new ArraySegment<byte> (new byte[0]), WebSocketMessageType.Text, true, CancellationToken.None).Wait (5000));
                        } catch (AggregateException e) {
-                               AssertWebSocketException (e, WebSocketError.Success);
+                               AssertWebSocketException (e, WebSocketError.InvalidState);
                                return;
                        }
                        Assert.Fail ("Should have thrown");
@@ -241,7 +241,7 @@ namespace MonoTests.System.Net.WebSockets
                                Assert.IsTrue (socket.CloseOutputAsync (WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait (5000));
                                Assert.IsTrue (socket.SendAsync (new ArraySegment<byte> (new byte[0]), WebSocketMessageType.Text, true, CancellationToken.None).Wait (5000));
                        } catch (AggregateException e) {
-                               AssertWebSocketException (e, WebSocketError.Success);
+                               AssertWebSocketException (e, WebSocketError.InvalidState);
                                return;
                        }
                        Assert.Fail ("Should have thrown");
@@ -296,7 +296,6 @@ namespace MonoTests.System.Net.WebSockets
                void AssertWebSocketException (AggregateException e, WebSocketError error, Type inner = null)
                {
                        var wsEx = e.InnerException as WebSocketException;
-                       Console.WriteLine (e.InnerException.ToString ());
                        Assert.IsNotNull (wsEx, "Not a websocketexception");
                        Assert.AreEqual (error, wsEx.WebSocketErrorCode);
                        if (inner != null) {
index c53bd72e937d8003767a1524bc8bb5b3ff5327a7..d267172d5b6fc081f5b26a7e615e9354f7ae8d04 100644 (file)
@@ -155,18 +155,6 @@ System.Net.Sockets/SocketReceiveFromResult.cs
 System.Net.Sockets/SocketReceiveMessageFromResult.cs
 System.Net.Sockets/SocketTaskExtensions.cs
 
-System.Net.WebSockets/ClientWebSocket.cs
-System.Net.WebSockets/ClientWebSocketOptions.cs
-System.Net.WebSockets/HttpListenerWebSocketContext.cs
-System.Net.WebSockets/WebSocket.cs
-System.Net.WebSockets/WebSocketCloseStatus.cs
-System.Net.WebSockets/WebSocketContext.cs
-System.Net.WebSockets/WebSocketError.cs
-System.Net.WebSockets/WebSocketException.cs
-System.Net.WebSockets/WebSocketMessageType.cs
-System.Net.WebSockets/WebSocketReceiveResult.cs
-System.Net.WebSockets/WebSocketState.cs
-
 System.Runtime.InteropServices.ComTypes/ADVF.cs
 System.Runtime.InteropServices.ComTypes/DATADIR.cs
 System.Runtime.InteropServices.ComTypes/DVASPECT.cs
@@ -927,12 +915,28 @@ ReferenceSources/Win32Exception.cs
 
 corefx/SR.cs
 
+../../../external/corefx/src/Common/src/System/StringExtensions.cs
+
 ../../../external/corefx/src/Common/src/System/Collections/Generic/ArrayBuilder.cs
 ../../../external/corefx/src/Common/src/System/Collections/Generic/EnumerableHelpers.cs
 ../../../external/corefx/src/Common/src/System/Collections/Generic/LargeArrayBuilder.cs
 
+../../../external/corefx/src/Common/src/System/Net/SecurityProtocol.cs
+../../../external/corefx/src/Common/src/System/Net/UriScheme.cs
+
+../../../external/corefx/src/Common/src/System/Net/Logging/NetEventSource.Common.cs
+
+../../../external/corefx/src/Common/src/System/Net/WebSockets/ManagedWebSocket.cs
+../../../external/corefx/src/Common/src/System/Net/WebSockets/WebSocketValidate.cs
+
 ../../../external/corefx/src/System.Runtime/src/System/Collections/Generic/ISet.cs
 
+../../../external/corefx/src/System.Buffers/src/System/Buffers/ArrayPool.cs
+../../../external/corefx/src/System.Buffers/src/System/Buffers/ArrayPoolEventSource.cs
+../../../external/corefx/src/System.Buffers/src/System/Buffers/DefaultArrayPool.cs
+../../../external/corefx/src/System.Buffers/src/System/Buffers/DefaultArrayPoolBucket.cs
+../../../external/corefx/src/System.Buffers/src/System/Buffers/Utilities.cs
+
 ../../../external/corefx/src/System.Collections/src/System/Collections/Generic/BitHelper.cs
 ../../../external/corefx/src/System.Collections/src/System/Collections/Generic/ICollectionDebugView.cs
 ../../../external/corefx/src/System.Collections/src/System/Collections/Generic/IDictionaryDebugView.cs
@@ -955,4 +959,19 @@ corefx/SR.cs
 ../../../external/corefx/src/System.IO.Compression/src/System/IO/Compression/CompressionMode.cs
 ../../../external/corefx/src/System.IO.Compression/src/System/IO/Compression/GZipStream.cs
 
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocket.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketContext.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketError.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketException.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketMessageType.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketReceiveResult.cs
+../../../external/corefx/src/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketState.cs
+
+../../../external/corefx/src/System.Net.WebSockets.Client/src/System/Net/WebSockets/ClientWebSocket.cs
+../../../external/corefx/src/System.Net.WebSockets.Client/src/System/Net/WebSockets/ClientWebSocketOptions.cs
+../../../external/corefx/src/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs
+
+../../../external/corefx/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
+
 ../../../external/corefx/src/System.Runtime.Extensions/src/System/CodeDom/Compiler/IndentedTextWriter.cs
index d4b44ad444f0da93bb11458becea41b652001cc9..733acc5e21fad3d1d77a5ac1bebab195665aa426 100644 (file)
@@ -79,4 +79,5 @@ partial class SR
        public const string Serialization_MismatchedCount = "The serialized Count information doesn't match the number of items.";
        public const string Serialization_MissingKeys = "The keys for this dictionary are missing.";
        public const string Serialization_MissingValues = "The values for this dictionary are missing.";
+       public const string ArgumentException_BufferNotFromPool = "The buffer is not associated with this pool and may not be returned to it.";
 }
index 60e5cae4053d79af6d58e1f1e32d691095e38850..0b3eb092e74c5d963d391209c6ba14d699d54c2a 100644 (file)
@@ -4,7 +4,6 @@ System.Net.Security/SslStream.platformnotsupported.cs
 System.Net.Sockets/TcpClient.platformnotsupported.cs
 System.Net.Sockets/TcpListener.platformnotsupported.cs
 System.Net.Sockets/UdpClient.platformnotsupported.cs
-System.Net.WebSockets/ClientWebSocket.platformnotsupported.cs
 System.Net/AuthenticationManager.platformnotsupported.cs
 System.Net/FtpRequestCreator.platformnotsupported.cs
 System.Net/FtpWebRequest.platformnotsupported.cs
diff --git a/mcs/class/System/orbis_System.dll.exclude.sources b/mcs/class/System/orbis_System.dll.exclude.sources
new file mode 100644 (file)
index 0000000..88149d6
--- /dev/null
@@ -0,0 +1,2 @@
+System.Net/MacProxy.cs
+System.Security.Cryptography.X509Certificates/OSX509Certificates.cs
index 06546720d6ca05c20fefb65c31797a4ed3d62fa1..4ad41e5a65ee09152c709804ea8035c0184365a9 100644 (file)
@@ -165,12 +165,15 @@ namespace System.IO.Packaging {
                                TargetMode mode = TargetMode.Internal;
                                if (node.Attributes["TargetMode"] != null)
                                        mode = (TargetMode) Enum.Parse (typeof(TargetMode), node.Attributes ["TargetMode"].Value);
-                               
-                               CreateRelationship (new Uri (node.Attributes["Target"].Value.ToString(), UriKind.RelativeOrAbsolute),
-                                                   mode,
-                                                   node.Attributes["Type"].Value.ToString (),
-                                                   node.Attributes["Id"].Value.ToString (),
-                                                   true);
+
+                               // Workaround for Mono relative paths
+                               // http://www.mono-project.com/docs/faq/known-issues/urikind-relativeorabsolute/
+                               var kind = (UriKind) 300;
+                               CreateRelationship (new Uri (node.Attributes["Target"].Value.ToString(), kind),
+                                                                       mode,
+                                                                       node.Attributes["Type"].Value.ToString (),
+                                                                       node.Attributes["Id"].Value.ToString (),
+                                                                       true);
                        }
                }
 
index bfea3c84973f2a9d7e29f733c4559e65c4f964ad..7ee53ac327a999d3bf33b1ec4d2f947dc56371a1 100644 (file)
@@ -215,5 +215,42 @@ namespace MonoTests.System.IO.Packaging
             \r
             return pack;\r
         }\r
+\r
+        Package CreateSpreadsheet(Stream stream)\r
+        {\r
+            Package pack = Package.Open(stream, FileMode.Create);\r
+\r
+            // Create package parts.\r
+            PackagePart workbookPart = pack.CreatePart(new Uri("/xl/workbook.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");\r
+            PackagePart sharedStringsPart = pack.CreatePart(new Uri("/xl/sharedStrings.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");\r
+\r
+            workbookPart.CreateRelationship(new Uri("/xl/sharedStrings.xml", UriKind.Relative), TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "rel1");\r
+\r
+            // Load some basic data into the different parts.\r
+            foreach (PackagePart part in package.GetParts())\r
+                using (Stream s = part.GetStream())\r
+                    s.Write(new byte[10], 0, 10);\r
+\r
+            return pack;\r
+        }\r
+\r
+        [Test]\r
+        public void TestExcelWorkbook()\r
+        {\r
+            MemoryStream stream = new MemoryStream();\r
+            Package package = CreateSpreadsheet(stream);\r
+            Assert.IsTrue(package.PartExists(new Uri("/xl/workbook.xml", UriKind.Relative)), "#1");\r
+            Assert.IsTrue(package.PartExists(new Uri("/xl/sharedStrings.xml", UriKind.Relative)), "#2");\r
+\r
+            package.Close();\r
+            package = Package.Open(new MemoryStream(stream.ToArray()), FileMode.Open);\r
+\r
+            PackagePart workbookPart = package.GetPart(new Uri("/xl/workbook.xml", UriKind.Relative));\r
+            Assert.IsTrue(workbookPart.RelationshipExists("rel1"), "#3");\r
+\r
+            var r = workbookPart.GetRelationship("rel1");\r
+            Assert.IsFalse(r.TargetUri.IsAbsoluteUri, "#4");\r
+            package.Close();\r
+        }\r
     }\r
 }\r
index 91b3709e63f41f430c71bc1e8bd29bbdb12cf979..946647ae149da3a979b204fbb60b6fb4a704e051 100644 (file)
@@ -40,9 +40,6 @@ using System.Runtime.InteropServices;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Runtime.ConstrainedExecution;
-#if !FULL_AOT_RUNTIME
-using System.Reflection.Emit;
-#endif
 
 namespace System
 {
@@ -114,45 +111,9 @@ namespace System
                        return false;
                }
 
-               int IList.IndexOf (object value)
+               internal void InternalArray__ICollection_CopyTo<T> (T[] array, int arrayIndex)
                {
-                       if (this.Rank > 1)
-                               throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
-
-                       int length = this.Length;
-                       for (int i = 0; i < length; i++) {
-                               if (Object.Equals (this.GetValueImpl (i), value))
-                                       // array index may not be zero-based.
-                                       // use lower bound
-                                       return i + this.GetLowerBound (0);
-                       }
-
-                       unchecked {
-                               // lower bound may be MinValue
-                               return this.GetLowerBound (0) - 1;
-                       }
-               }
-
-               internal void InternalArray__ICollection_CopyTo<T> (T[] array, int index)
-               {
-                       if (array == null)
-                               throw new ArgumentNullException ("array");
-
-                       // The order of these exception checks may look strange,
-                       // but that's how the microsoft runtime does it.
-                       if (this.Rank > 1)
-                               throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
-                       if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
-                               throw new ArgumentException ("Destination array was not long " +
-                                       "enough. Check destIndex and length, and the array's " +
-                                       "lower bounds.");
-                       if (array.Rank > 1)
-                               throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
-                       if (index < 0)
-                               throw new ArgumentOutOfRangeException (
-                                       "index", Locale.GetText ("Value has to be >= 0."));
-
-                       Copy (this, this.GetLowerBound (0), array, index, this.GetLength (0));
+                       Copy (this, GetLowerBound (0), array, arrayIndex, Length);
                }
 
                internal T InternalArray__IReadOnlyList_get_Item<T> (int index)
@@ -342,12 +303,6 @@ namespace System
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal extern static Array CreateInstanceImpl (Type elementType, int[] lengths, int[] bounds);
 
-               public bool IsReadOnly {
-                       get {
-                               return false;
-                       }
-               }
-
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public int GetUpperBound (int dimension)
                {
@@ -377,50 +332,6 @@ namespace System
                        return GetValue (ind);
                }
 
-               [ComVisible (false)]
-               public void SetValue (object value, long index)
-               {
-                       if (index < 0 || index > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       SetValue (value, (int) index);
-               }
-
-               [ComVisible (false)]
-               public void SetValue (object value, long index1, long index2)
-               {
-                       if (index1 < 0 || index1 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index1", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       if (index2 < 0 || index2 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index2", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       int[] ind = {(int) index1, (int) index2};
-                       SetValue (value, ind);
-               }
-
-               [ComVisible (false)]
-               public void SetValue (object value, long index1, long index2, long index3)
-               {
-                       if (index1 < 0 || index1 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index1", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       if (index2 < 0 || index2 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index2", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       if (index3 < 0 || index3 > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("index3", Locale.GetText (
-                                       "Value must be >= 0 and <= Int32.MaxValue."));
-
-                       int[] ind = {(int) index1, (int) index2, (int) index3};
-                       SetValue (value, ind);
-               }
-
                public void SetValue (object value, int index)
                {
                        if (Rank != 1)
@@ -499,10 +410,6 @@ namespace System
                                throw new NotSupportedException ("Array type can not be void");
                        if (elementType.ContainsGenericParameters)
                                throw new NotSupportedException ("Array type can not be an open generic type");
-#if !FULL_AOT_RUNTIME
-                       if ((elementType is TypeBuilder) && !(elementType as TypeBuilder).IsCreated ())
-                               throw new NotSupportedException ("Can't create an array of the unfinished type '" + elementType + "'.");
-#endif
                        
                        return CreateInstanceImpl (elementType, lengths, bounds);
                }
@@ -545,36 +452,6 @@ namespace System
                        return CreateInstanceImpl (elementType, lengths, lowerBounds);
                }
 
-               static int [] GetIntArray (long [] values)
-               {
-                       int len = values.Length;
-                       int [] ints = new int [len];
-                       for (int i = 0; i < len; i++) {
-                               long current = values [i];
-                               if (current < 0 || current > (long) Int32.MaxValue)
-                                       throw new ArgumentOutOfRangeException ("values", Locale.GetText (
-                                               "Each value has to be >= 0 and <= Int32.MaxValue."));
-
-                               ints [i] = (int) current;
-                       }
-                       return ints;
-               }
-
-               public static Array CreateInstance (Type elementType, params long [] lengths)
-               {
-                       if (lengths == null)
-                               throw new ArgumentNullException ("lengths");
-                       return CreateInstance (elementType, GetIntArray (lengths));
-               }
-
-               [ComVisible (false)]
-               public void SetValue (object value, params long [] indices)
-               {
-                       if (indices == null)
-                               throw new ArgumentNullException ("indices");
-                       SetValue (value, GetIntArray (indices));
-               }
-
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public static void Clear (Array array, int index, int length)
                {
@@ -712,7 +589,7 @@ namespace System
                        return source.IsAssignableFrom (target) || target.IsAssignableFrom (source);
                }
 
-               public static T [] FindAll<T> (T [] array, Predicate <T> match)
+               public static T[] FindAll<T> (T[] array, Predicate<T> match)
                {
                        if (array == null)
                                throw new ArgumentNullException ("array");
@@ -721,12 +598,19 @@ namespace System
                                throw new ArgumentNullException ("match");
 
                        int pos = 0;
-                       T [] d = new T [array.Length];
-                       foreach (T t in array)
-                               if (match (t))
-                                       d [pos++] = t;
+                       T[] d = Empty<T>();
+                       for (int i = 0; i < array.Length; i++) {
+                               if (match (array [i])) {
+                                       if (pos == d.Length)
+                                               Resize (ref d, pos == 0 ? 4 : pos * 2);
+
+                                       d [pos++] = array [i];
+                               }
+                       }
+
+                       if (pos != d.Length)
+                               Resize (ref d, pos);
 
-                       Resize <T> (ref d, pos);
                        return d;
                }
 
index 7eb3bc08918c58c05a5f4291af4b338edd555e3b..96e4ee325f41cb8cb7d6fa93342a7df8fab58fff 100644 (file)
@@ -19,6 +19,26 @@ namespace System
 {
     public abstract partial class Array : ICollection, IEnumerable, IList, IStructuralComparable, IStructuralEquatable, ICloneable
     {
+        public static Array CreateInstance(Type elementType, params long[] lengths)
+        {
+            if (lengths == null)
+                throw new ArgumentNullException(nameof(lengths));
+            if (lengths.Length == 0)
+                throw new ArgumentException(SR.Arg_NeedAtLeast1Rank);
+
+            int[] intLengths = new int[lengths.Length];
+
+            for (int i = 0; i < lengths.Length; ++i)
+            {
+                long len = lengths[i];
+                if (len > int.MaxValue || len < int.MinValue)
+                    throw new ArgumentOutOfRangeException("len", SR.ArgumentOutOfRange_HugeArrayNotSupported);
+                intLengths[i] = (int)len;
+            }
+
+            return Array.CreateInstance(elementType, intLengths);
+        }
+
         public static ReadOnlyCollection<T> AsReadOnly<T>(T[] array)
         {
             if (array == null)
@@ -83,7 +103,12 @@ namespace System
 
         void IList.Clear()
         {
-            Array.Clear(this, 0, this.Length);
+            Array.Clear(this, GetLowerBound(0), this.Length);
+        }
+
+        int IList.IndexOf(Object value)
+        {
+            return Array.IndexOf(this, value);
         }
 
         void IList.Insert(int index, Object value)
@@ -114,7 +139,7 @@ namespace System
             if (array != null && array.Rank != 1)
                 throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
 
-            Array.Copy(this, 0, array, index, Length);
+            Array.Copy(this, GetLowerBound(0), array, index, Length);
         }
 
         // Make a new array which is a deep copy of the original array.
@@ -226,7 +251,7 @@ namespace System
         {
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
-            return BinarySearch(array, 0, array.Length, value, null);
+            return BinarySearch(array, array.GetLowerBound(0), array.Length, value, null);
         }
 
         public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter)
@@ -380,6 +405,8 @@ namespace System
 
         public bool IsFixedSize { get { return true; } }
 
+        public bool IsReadOnly { get { return false; } }
+
         // Is this Array synchronized (i.e., thread-safe)?  If you want a synchronized
         // collection, you can use SyncRoot as an object to synchronize your 
         // collection with.  You could also call GetSynchronized() 
@@ -426,7 +453,7 @@ namespace System
         {
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
-            return BinarySearch(array, 0, array.Length, value, comparer);
+            return BinarySearch(array, array.GetLowerBound(0), array.Length, value, comparer);
         }
 
         // Searches a section of an array for a given element using a binary search
@@ -565,7 +592,7 @@ namespace System
                 throw new ArgumentNullException(nameof(array));
             }
 
-            return IndexOf(array, value, 0, array.Length);
+            return IndexOf(array, value, array.GetLowerBound(0), array.Length);
         }
 
         // Returns the index of the first occurrence of a given value in a range of
@@ -581,7 +608,8 @@ namespace System
                 throw new ArgumentNullException(nameof(array));
             }
 
-            return IndexOf(array, value, startIndex, array.Length - startIndex);
+            int lb = array.GetLowerBound(0);
+            return IndexOf(array, value, startIndex, array.Length - startIndex + lb);
         }
 
         // Returns the index of the first occurrence of a given value in a range of
@@ -596,9 +624,10 @@ namespace System
                 throw new ArgumentNullException(nameof(array));
             if (array.Rank != 1)
                 throw new RankException(SR.Rank_MultiDimNotSupported);
-            if (startIndex < 0 || startIndex > array.Length)
+            int lb = array.GetLowerBound(0);
+            if (startIndex < lb || startIndex > array.Length + lb)
                 throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
-            if (count < 0 || count > array.Length - startIndex)
+            if (count < 0 || count > array.Length - startIndex + lb)
                 throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
 
             Object[] objArray = array as Object[];
@@ -636,7 +665,7 @@ namespace System
                     }
                 }
             }
-            return -1;
+            return lb - 1;
         }
 
         /// <summary>
@@ -903,7 +932,7 @@ namespace System
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
 
-            Reverse(array, 0, array.Length);
+            Reverse(array, array.GetLowerBound(0), array.Length);
         }
 
         // Reverses the elements in a range of an array. Following a call to this
@@ -980,6 +1009,56 @@ namespace System
             }
         }
 
+        public void SetValue(object value, long index)
+        {
+            if (index > int.MaxValue || index < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+
+            SetValue(value, (int)index);
+        }
+
+        public void SetValue(object value, long index1, long index2)
+        {
+            if (index1 > int.MaxValue || index1 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index1), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+            if (index2 > int.MaxValue || index2 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index2), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+
+            SetValue(value, (int)index1, (int)index2);
+        }
+
+        public void SetValue(object value, long index1, long index2, long index3)
+        {
+            if (index1 > int.MaxValue || index1 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index1), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+            if (index2 > int.MaxValue || index2 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index2), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+            if (index3 > int.MaxValue || index3 < int.MinValue)
+                throw new ArgumentOutOfRangeException(nameof(index3), SR.ArgumentOutOfRange_HugeArrayNotSupported);
+
+            SetValue(value, (int)index1, (int)index2, (int)index3);
+        }
+
+        public void SetValue(object value, params long[] indices)
+        {
+            if (indices == null)
+                throw new ArgumentNullException(nameof(indices));
+            if (Rank != indices.Length)
+                throw new ArgumentException(SR.Arg_RankIndices);
+
+            int[] intIndices = new int[indices.Length];
+
+            for (int i = 0; i < indices.Length; ++i)
+            {
+                long index = indices[i];
+                if (index > int.MaxValue || index < int.MinValue)
+                    throw new ArgumentOutOfRangeException("index", SR.ArgumentOutOfRange_HugeArrayNotSupported);
+                intIndices[i] = (int)index;
+            }
+
+            SetValue(value, intIndices);
+        }
+
         // Sorts the elements of an array. The sort compares the elements to each
         // other using the IComparable interface, which must be implemented
         // by all elements of the array.
@@ -989,7 +1068,7 @@ namespace System
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
 
-            Sort(array, null, 0, array.Length, null);
+            Sort(array, null, array.GetLowerBound(0), array.Length, null);
         }
 
         // Sorts the elements in a section of an array. The sort compares the
@@ -1012,7 +1091,7 @@ namespace System
             if (array == null)
                 throw new ArgumentNullException(nameof(array));
 
-            Sort(array, null, 0, array.Length, comparer);
+            Sort(array, null, array.GetLowerBound(0), array.Length, comparer);
         }
 
         // Sorts the elements in a section of an array. The sort compares the
index 519786c3cf2af60442895a8c1350b26edc2950e1..425a983215473970ab5484bc9602437ff53b41fb 100644 (file)
@@ -6,17 +6,41 @@ all-local:
 
 PROFILE_DIR=$(DESTDIR)$(mono_libdir)/mono
 
+build-reference-assemblies:
+       $(MAKE) -C ../../../external/binary-reference-assemblies CSC="MONO_PATH=$(abspath $(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)) $(INTERNAL_CSC)"
+
 install-local:
        $(MKINSTALLDIRS) $(PROFILE_DIR)/2.0-api
        $(MKINSTALLDIRS) $(PROFILE_DIR)/3.5-api
        $(MKINSTALLDIRS) $(PROFILE_DIR)/4.0-api
        $(MKINSTALLDIRS) $(PROFILE_DIR)/4.5-api
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.5.1-api
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.5.2-api
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.6-api
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.6.1-api
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.6.2-api
        $(MKINSTALLDIRS) $(PROFILE_DIR)/4.5-api/Facades
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.5.1-api/Facades
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.5.2-api/Facades
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.6-api/Facades
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.6.1-api/Facades
+       $(MKINSTALLDIRS) $(PROFILE_DIR)/4.6.2-api/Facades
+
        $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v2.0/*.dll $(PROFILE_DIR)/2.0-api
        $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v3.5/*.dll $(PROFILE_DIR)/3.5-api
        $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.0/*.dll $(PROFILE_DIR)/4.0-api
        $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5/*.dll $(PROFILE_DIR)/4.5-api
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5.1/*.dll $(PROFILE_DIR)/4.5.1-api
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5.2/*.dll $(PROFILE_DIR)/4.5.2-api
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.6/*.dll $(PROFILE_DIR)/4.6-api
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.6.1/*.dll $(PROFILE_DIR)/4.6.1-api
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.6.2/*.dll $(PROFILE_DIR)/4.6.2-api
        $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5/Facades/*.dll $(PROFILE_DIR)/4.5-api/Facades
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5.1/Facades/*.dll $(PROFILE_DIR)/4.5.1-api/Facades
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5.2/Facades/*.dll $(PROFILE_DIR)/4.5.2-api/Facades
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.6/Facades/*.dll $(PROFILE_DIR)/4.6-api/Facades
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.6.1/Facades/*.dll $(PROFILE_DIR)/4.6.1-api/Facades
+       $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.6.2/Facades/*.dll $(PROFILE_DIR)/4.6.2-api/Facades
 
        # Unfortunately, a few programs (most notably NUnit and FSharp) have hardcoded checks for <prefix>/lib/mono/4.0/mscorlib.dll or Mono.Posix.dll,
        # so we need to place something there or those tools break. We decided to symlink to the reference assembly for now.
@@ -25,6 +49,47 @@ install-local:
        ln -sf ../4.0-api/mscorlib.dll $(PROFILE_DIR)/4.0/mscorlib.dll
        ln -sf ../4.0-api/Mono.Posix.dll $(PROFILE_DIR)/4.0/Mono.Posix.dll
 
-DISTFILES = $(wildcard ../../../external/binary-reference-assemblies/v4.5/Facades/*.dll) $(wildcard ../../../external/binary-reference-assemblies/v4.5/*.dll) $(wildcard ../../../external/binary-reference-assemblies/v4.0/*.dll) $(wildcard ../../../external/binary-reference-assemblies/v3.5/*.dll) $(wildcard ../../../external/binary-reference-assemblies/v2.0/*.dll) Makefile
+DISTFILES =    \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.6.2/Facades/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.6.1/Facades/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.6/Facades/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.5.2/Facades/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.5.1/Facades/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.5/Facades/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.6.2/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.6.1/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.6/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.5.2/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.5.1/*.dll)  \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.5/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/v4.0/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/v3.5/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/v2.0/*.dll)    \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.6.2/Facades/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.6.1/Facades/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.6/Facades/*.cs) \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.5.2/Facades/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.5.1/Facades/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.5/Facades/*.cs) \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.6.2/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.6.1/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.6/*.cs) \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.5.2/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.5.1/*.cs)       \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.5/*.cs) \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v4.0/*.cs) \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v3.5/*.cs) \
+       $(wildcard ../../../external/binary-reference-assemblies/src/v2.0/*.cs) \
+       ../../../external/binary-reference-assemblies/v4.6.2/Makefile   \
+       ../../../external/binary-reference-assemblies/v4.6.1/Makefile   \
+       ../../../external/binary-reference-assemblies/v4.6/Makefile     \
+       ../../../external/binary-reference-assemblies/v4.5.2/Makefile   \
+       ../../../external/binary-reference-assemblies/v4.5.1/Makefile   \
+       ../../../external/binary-reference-assemblies/v4.5/Makefile     \
+       ../../../external/binary-reference-assemblies/v4.0/Makefile     \
+       ../../../external/binary-reference-assemblies/v3.5/Makefile     \
+       ../../../external/binary-reference-assemblies/v2.0/Makefile     \
+       ../../../external/binary-reference-assemblies/Makefile  \
+       Makefile
 
 dist-local: dist-default
index b4ec154380d1bad74d5eb0f6a6c5e9e3e865fd66..80fef4d94d1ba5c65c20b16a99a0e26f2e8b79e5 100644 (file)
@@ -504,7 +504,7 @@ namespace System.Net {
 #if MONO
         public static IWebProxy CreateDefaultProxy ()
         {
-#if FEATURE_NO_BSD_SOCKETS
+#if FEATURE_NO_BSD_SOCKETS || ORBIS
             throw new PlatformNotSupportedException ();
 #elif MONOTOUCH
             return Mono.Net.CFNetwork.GetDefaultProxy ();
index 26f870d93858ce03ed842bd774fce8f2bf86d2a8..1243712f160dac5db9e9b50b7c6057cf385d6f11 100644 (file)
@@ -249,7 +249,12 @@ namespace Mono.CSharp
                        sdk_directory.Add ("4", new string[] { "4.0-api", "v4.0.30319" });
                        sdk_directory.Add ("4.0", new string[] { "4.0-api", "v4.0.30319" });
                        sdk_directory.Add ("4.5", new string[] { "4.5-api", "v4.0.30319" });
-                       sdk_directory.Add ("4.6", new string [] { "4.5", "net_4_x", "v4.0.30319" });
+                       sdk_directory.Add ("4.5.1", new string[] { "4.5.1-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.5.2", new string[] { "4.5.2-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.6", new string[] { "4.6-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.6.1", new string[] { "4.6.1-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.6.2", new string [] { "4.6.2-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.x", new string [] { "4.5", "net_4_x", "v4.0.30319" });
                }
 
                public StaticLoader (StaticImporter importer, CompilerContext compiler)
@@ -269,7 +274,7 @@ namespace Mono.CSharp
 
                                string sdk_path = null;
 
-                               string sdk_version = compiler.Settings.SdkVersion ?? "4.6";
+                               string sdk_version = compiler.Settings.SdkVersion ?? "4.x";
                                string[] sdk_sub_dirs;
 
                                if (!sdk_directory.TryGetValue (sdk_version, out sdk_sub_dirs))
index d9f2d5ed386078c4bb96df1b2105fd4c2108e41a..cd1f0d86f65ba7b22e83d0d21d6c9a4135c68a31 100644 (file)
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FileList  Name=".NET Framework 4.5.1" TargetFrameworkDirectory="..\..\..\..\4.5-api">
+<FileList  Name=".NET Framework 4.5.1" TargetFrameworkDirectory="..\..\..\..\4.5.1-api">
 </FileList>
index bf92045249c3b7d3984a08146f54ce51756e5041..1eab465c6adf9f283ebe731569a9b02a1032753d 100644 (file)
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FileList  Name=".NET Framework 4.5.2" TargetFrameworkDirectory="..\..\..\..\4.5-api">
+<FileList  Name=".NET Framework 4.5.2" TargetFrameworkDirectory="..\..\..\..\4.5.2-api">
 </FileList>
index 9fa1fda25ed8f9845567b1cef1fe13f4449616f6..90dd7771941bfeeefed51637d2bc66e4be51fa8f 100644 (file)
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FileList  Name=".NET Framework 4.6.1" TargetFrameworkDirectory="..\..\..\..\4.5">
+<FileList  Name=".NET Framework 4.6.1" TargetFrameworkDirectory="..\..\..\..\4.6.1-api">
 </FileList>
index 2865ecb622b78bda4ecf283011be8ae987356adc..ba7d9f325697c5272cd695b4d4756f2001c306cd 100644 (file)
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FileList  Name=".NET Framework 4.6.2" TargetFrameworkDirectory="..\..\..\..\4.5">
+<FileList  Name=".NET Framework 4.6.2" TargetFrameworkDirectory="..\..\..\..\4.6.2-api">
 </FileList>
index a2ba03d987b2de0c3222c5a04b0b6e155d09a6a1..191215d23bfe96380212cb20c7cad41cc11c1789 100644 (file)
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FileList  Name=".NET Framework 4.6" TargetFrameworkDirectory="..\..\..\..\4.5">
+<FileList  Name=".NET Framework 4.6" TargetFrameworkDirectory="..\..\..\..\4.6-api">
 </FileList>
index 97e1aefcb1ed5299f1aae55d93c34caf14685029..93d85a57df3ec32061809e92309d1b064a4d5649 100644 (file)
@@ -52,11 +52,12 @@ mono_disassemble_code (guint8 *code, int size, char *id)
        system (cmd); 
        g_free (cmd);
        if (!objdump_args)
-               objdump_args = "";
+               objdump_args = strdup("");
        
        cmd = g_strdup_printf (DIS_CMD " %s %s", objdump_args, o_file);
        system (cmd);
        g_free (cmd);
+       g_free (objdump_args);
        
        g_free (o_file);
        g_free (as_file);
index c8ef14eaeed3dd86d814920839c14dc6ddd56398..cafb55618910fee90f6ffbdb45ae51ad053cea12 100644 (file)
 <opcode name="mono_lddomain" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x19" flow="next" />
 <opcode name="mono_atomic_store_i4" input="PopI+PopI" output="Push0" args="InlineI" o1="0xF0" o2="0x1A" flow="next" />
 <opcode name="mono_get_last_error" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x1B" flow="next" />
+<opcode name="mono_get_rgctx_arg" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x1C" flow="next" />
 </opdesc>
index fca2448151a9771b1a91e6fed9d4b130147559b1..91e8924febc18e66763e669964aea5d8352ab2c5 100644 (file)
@@ -320,6 +320,7 @@ OPDEF(CEE_MONO_CALLI_EXTRA_ARG, "mono_calli_extra_arg", VarPop, VarPush, InlineS
 OPDEF(CEE_MONO_LDDOMAIN, "mono_lddomain", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x19, NEXT)
 OPDEF(CEE_MONO_ATOMIC_STORE_I4, "mono_atomic_store_i4", PopI+PopI, Push0, InlineI, X, 2, 0xF0, 0x1A, NEXT)
 OPDEF(CEE_MONO_GET_LAST_ERROR, "mono_get_last_error", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x1B, NEXT)
+OPDEF(CEE_MONO_GET_RGCTX_ARG, "mono_get_rgctx_arg", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x1C, NEXT)
 #ifndef OPALIAS
 #define _MONO_CIL_OPALIAS_DEFINED_
 #define OPALIAS(a,s,r)
index bfd0a23e506637525fb7cc13ec5a10c9f611398c..790dc504ed56b80fb71f8b2249a5eb0070eb2531 100644 (file)
@@ -2208,8 +2208,9 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id, MonoError *error)
         * Unloading seems to cause problems when running NUnit/NAnt, hence
         * this workaround.
         */
-       if (g_getenv ("MONO_NO_UNLOAD"))
+       if (g_hasenv ("MONO_NO_UNLOAD"))
                return;
+
 #ifdef __native_client__
        return;
 #endif
index 097ce878007517266c8bdec27627ea0dd25267bb..9178bb837d557a1ba439480048a49c1718a94d89 100644 (file)
@@ -295,7 +295,7 @@ mono_set_assemblies_path (const char* path)
        }
        *dest = *splitted;
 
-       if (g_getenv ("MONO_DEBUG") == NULL)
+       if (g_hasenv ("MONO_DEBUG"))
                return;
 
        splitted = assemblies_path;
@@ -316,21 +316,25 @@ char* nacl_mono_path = NULL;
 static void
 check_path_env (void)
 {
-       const char* path;
-       path = g_getenv ("MONO_PATH");
+       if (assemblies_path != NULL)
+               return;
+
+       char* path = g_getenv ("MONO_PATH");
 #ifdef __native_client__
        if (!path)
-               path = nacl_mono_path;
+               path = strdup (nacl_mono_path);
 #endif
-       if (!path || assemblies_path != NULL)
+       if (!path)
                return;
 
        mono_set_assemblies_path(path);
+       g_free (path);
 }
 
 static void
-check_extra_gac_path_env (void) {
-       const char *path;
+check_extra_gac_path_env (void) 
+{
+       char *path;
        char **splitted, **dest;
        
        path = g_getenv ("MONO_GAC_PREFIX");
@@ -338,6 +342,8 @@ check_extra_gac_path_env (void) {
                return;
 
        splitted = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 1000);
+       g_free (path);
+
        if (extra_gac_paths)
                g_strfreev (extra_gac_paths);
        extra_gac_paths = dest = splitted;
@@ -348,7 +354,7 @@ check_extra_gac_path_env (void) {
        }
        *dest = *splitted;
        
-       if (g_getenv ("MONO_DEBUG") == NULL)
+       if (!g_hasenv ("MONO_DEBUG"))
                return;
 
        while (*splitted) {
index 107022576d02563a69f22a4e2c76e193d77f5b5b..8adf077e6b1956fca0f4f3accd195b8b72394126 100644 (file)
@@ -199,6 +199,7 @@ mono_gc_base_init (void)
                                        log_finalizers = 1;
                                }
                        }
+                       g_free (env);
                }
        }
 
@@ -242,6 +243,7 @@ mono_gc_base_init (void)
                                */
                        }
                }
+               g_free (env);
                g_strfreev (opts);
        }
 
@@ -1320,7 +1322,7 @@ mono_gc_is_moving (void)
 gboolean
 mono_gc_is_disabled (void)
 {
-       if (GC_dont_gc || g_getenv ("GC_DONT_GC"))
+       if (GC_dont_gc || g_hasenv ("GC_DONT_GC"))
                return TRUE;
        else
                return FALSE;
index 1a2970b1e6bb37ad0d35ba84fa925cb3ef372aa4..cd15ef8ea77dda8f112f841eab872d4b241e10f5 100644 (file)
@@ -3687,7 +3687,7 @@ is_wcf_hack_disabled (void)
        static gboolean disabled;
        static gboolean inited = FALSE;
        if (!inited) {
-               disabled = g_getenv ("MONO_DISABLE_WCF_HACK") != NULL;
+               disabled = g_hasenv ("MONO_DISABLE_WCF_HACK");
                inited = TRUE;
        }
        return disabled;
@@ -4034,6 +4034,32 @@ mono_class_need_stelemref_method (MonoClass *klass)
        return klass->rank == 1 && MONO_TYPE_IS_REFERENCE (&klass->element_class->byval_arg);
 }
 
+static int
+apply_override (MonoClass *klass, MonoMethod **vtable, MonoMethod *decl, MonoMethod *override)
+{
+       int dslot;
+       dslot = mono_method_get_vtable_slot (decl);
+       if (dslot == -1) {
+               mono_class_set_type_load_failure (klass, "");
+               return FALSE;
+       }
+
+       dslot += mono_class_interface_offset (klass, decl->klass);
+       vtable [dslot] = override;
+       if (!MONO_CLASS_IS_INTERFACE (override->klass)) {
+               /*
+                * If override from an interface, then it is an override of a default interface method,
+                * don't override its slot.
+                */
+               vtable [dslot]->slot = dslot;
+       }
+
+       if (mono_security_core_clr_enabled ())
+               mono_security_core_clr_check_override (klass, vtable [dslot], decl);
+
+       return TRUE;
+}
+
 /*
  * LOCKING: this is supposed to be called with the loader lock held.
  */
@@ -4191,29 +4217,48 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
        }
 
        TRACE_INTERFACE_VTABLE (print_vtable_full (klass, vtable, cur_slot, first_non_interface_slot, "AFTER INHERITING PARENT VTABLE", TRUE));
+
+       /* Process overrides from interface default methods */
+       // FIXME: Ordering between interfaces
+       for (int ifindex = 0; ifindex < klass->interface_offsets_count; ifindex++) {
+               ic = klass->interfaces_packed [ifindex];
+
+               mono_class_setup_methods (ic);
+               if (mono_class_has_failure (ic))
+                       goto fail;
+
+               MonoMethod **iface_overrides;
+               int iface_onum;
+               gboolean ok = mono_class_get_overrides_full (ic->image, ic->type_token, &iface_overrides, &iface_onum, mono_class_get_context (ic));
+               if (ok) {
+                       for (int i = 0; i < iface_onum; i++) {
+                               MonoMethod *decl = iface_overrides [i*2];
+                               MonoMethod *override = iface_overrides [i*2 + 1];
+                               if (!apply_override (klass, vtable, decl, override))
+                                       goto fail;
+
+                               if (!override_map)
+                                       override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
+                               g_hash_table_insert (override_map, decl, override);
+                       }
+                       g_free (iface_overrides);
+               }
+       }
+
        /* override interface methods */
        for (i = 0; i < onum; i++) {
                MonoMethod *decl = overrides [i*2];
+               MonoMethod *override = overrides [i*2 + 1];
                if (MONO_CLASS_IS_INTERFACE (decl->klass)) {
-                       int dslot;
-                       dslot = mono_method_get_vtable_slot (decl);
-                       if (dslot == -1) {
-                               mono_class_set_type_load_failure (klass, "");
+                       if (!apply_override (klass, vtable, decl, override))
                                goto fail;
-                       }
 
-                       dslot += mono_class_interface_offset (klass, decl->klass);
-                       vtable [dslot] = overrides [i*2 + 1];
-                       vtable [dslot]->slot = dslot;
                        if (!override_map)
                                override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
-
-                       g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]);
-
-                       if (mono_security_core_clr_enabled ())
-                               mono_security_core_clr_check_override (klass, vtable [dslot], decl);
+                       g_hash_table_insert (override_map, decl, override);
                }
        }
+
        TRACE_INTERFACE_VTABLE (print_overrides (override_map, "AFTER OVERRIDING INTERFACE METHODS"));
        TRACE_INTERFACE_VTABLE (print_vtable_full (klass, vtable, cur_slot, first_non_interface_slot, "AFTER OVERRIDING INTERFACE METHODS", FALSE));
 
@@ -4319,6 +4364,13 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                                                TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("\n"));
                                        }
                                }
+
+                               if (vtable [im_slot] == NULL) {
+                                       if (!(im->flags & METHOD_ATTRIBUTE_ABSTRACT)) {
+                                               TRACE_INTERFACE_VTABLE (printf ("    Using default iface method %s.\n", mono_method_full_name (im, 1)));
+                                               vtable [im_slot] = im;
+                                       }
+                               }
                        } else {
                                g_assert (vtable [im_slot] == override_im);
                        }
index 84ddd824129bb829934999f43fa70cb5bf633ec1..86309ef20234d4dd559726f0c9fcfe1a32f08e32 100644 (file)
@@ -600,13 +600,15 @@ cominterop_type_from_handle (MonoType *handle)
 void
 mono_cominterop_init (void)
 {
-       const char* com_provider_env;
+       char* com_provider_env;
 
        mono_os_mutex_init_recursive (&cominterop_mutex);
 
        com_provider_env = g_getenv ("MONO_COM");
        if (com_provider_env && !strcmp(com_provider_env, "MS"))
                com_provider = MONO_COM_MS;
+       if (com_provider_env)
+               g_free (com_provider_env);
 
        register_icall (cominterop_get_method_interface, "cominterop_get_method_interface", "ptr ptr", FALSE);
        register_icall (cominterop_get_function_pointer, "cominterop_get_function_pointer", "ptr ptr int32", FALSE);
index 83145afb536bd489eaa70f3e958b0ccd4c43def9..749a43452d05b6066c6ed1fbc4d6ed3996bb4c35 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <mono/metadata/console-io.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/w32file.h>
+#include <mono/utils/w32api.h>
 
 void
 mono_console_init (void)
index 2ad4210f7563f413d0175f37021fcfe1b6fd8b40..98b3ba551cb005a3af4cbadc884cb576a81e4984 100644 (file)
@@ -457,12 +457,16 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardow
        if (dims == -1){
                int cols = 0, rows = 0;
                                      
-               const char *str = g_getenv ("COLUMNS");
-               if (str != NULL)
+               char *str = g_getenv ("COLUMNS");
+               if (str != NULL) {
                        cols = atoi (str);
+                       g_free (str);
+               }
                str = g_getenv ("LINES");
-               if (str != NULL)
+               if (str != NULL) {
                        rows = atoi (str);
+                       g_free (str);
+               }
 
                if (cols != 0 && rows != 0)
                        cols_and_lines = (cols << 16) | rows;
index 30643c8a760012c0e9abe68b0e832b9723f35e70..6611e02de6bf6a96a29b6ff242fd6392523675e6 100644 (file)
@@ -263,7 +263,7 @@ ICALL(ENUM_7, "get_value", ves_icall_System_Enum_get_value)
 
 ICALL_TYPE(ENV, "System.Environment", ENV_1)
 ICALL(ENV_1, "Exit", ves_icall_System_Environment_Exit)
-ICALL(ENV_2, "GetCommandLineArgs", ves_icall_System_Environment_GetCoomandLineArgs)
+ICALL(ENV_2, "GetCommandLineArgs", ves_icall_System_Environment_GetCommandLineArgs)
 ICALL(ENV_3, "GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames)
 ICALL(ENV_31, "GetIs64BitOperatingSystem", ves_icall_System_Environment_GetIs64BitOperatingSystem)
 ICALL(ENV_4, "GetLogicalDrivesInternal", ves_icall_System_Environment_GetLogicalDrives )
index 542dd85399dee7f6553102f9d9b72e547002e2bb..cb562cde7613af2419d55b049d8a3a7ece434449 100644 (file)
@@ -6518,7 +6518,7 @@ ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
 ICALL_EXPORT MonoStringHandle
 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
 {
-       const gchar *value;
+       gchar *value;
 
        if (utf8_name == NULL)
                return NULL_HANDLE_STRING;
@@ -6528,7 +6528,9 @@ ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_na
        if (value == 0)
                return NULL_HANDLE_STRING;
        
-       return mono_string_new_handle (mono_domain_get (), value, error);
+       MonoStringHandle res = mono_string_new_handle (mono_domain_get (), value, error);
+       g_free (value);
+       return res;
 }
 
 /*
@@ -6556,7 +6558,7 @@ char **environ;
 #endif
 
 ICALL_EXPORT MonoArray *
-ves_icall_System_Environment_GetCoomandLineArgs (void)
+ves_icall_System_Environment_GetCommandLineArgs (void)
 {
        MonoError error;
        MonoArray *result = mono_runtime_get_main_args_checked (&error);
index 688bc3c50ba3decfab81a59a1f5b476dfbc7aea0..eb4d686412e586b822e0f064748cc7e7117c2b64 100644 (file)
@@ -256,7 +256,7 @@ mono_images_init (void)
        for(hash_idx = 0; hash_idx < IMAGES_HASH_COUNT; hash_idx++)
                loaded_images_hashes [hash_idx] = g_hash_table_new (g_str_hash, g_str_equal);
 
-       debug_assembly_unload = g_getenv ("MONO_DEBUG_ASSEMBLY_UNLOAD") != NULL;
+       debug_assembly_unload = g_hasenv ("MONO_DEBUG_ASSEMBLY_UNLOAD");
 
        install_pe_loader ();
 
index 403199d0c9a2cc2d5fe1cfc6629f1bbd7d889ccf..c3800d5325fbc6e599fe7188b4150a52ee78b0e4 100644 (file)
@@ -479,22 +479,27 @@ get_darwin_locale (void)
 static char *
 get_posix_locale (void)
 {
-       const char *locale;
+       char *locale;
 
        locale = g_getenv ("LC_ALL");
        if (locale == NULL) {
                locale = g_getenv ("LANG");
-               if (locale == NULL)
-                       locale = setlocale (LC_ALL, NULL);
+               if (locale == NULL) {
+                       char *static_locale = setlocale (LC_ALL, NULL);
+                       if (static_locale)
+                               locale = g_strdup (static_locale);
+               }
        }
        if (locale == NULL)
                return NULL;
 
        /* Skip English-only locale 'C' */
-       if (strcmp (locale, "C") == 0)
+       if (strcmp (locale, "C") == 0) {
+               g_free (locale);
                return NULL;
+       }
 
-       return g_strdup (locale);
+       return locale;
 }
 
 
index 1ec84e6533be4aa4c2f718d06ab82e93e5010b3f..bda05487d5fde39a960e535e54c5e513a8e9b18d 100644 (file)
@@ -74,8 +74,10 @@ mono_locks_tracer_init (void)
        int res;
        char *name;
        mono_os_mutex_init_recursive (&tracer_lock);
-       if (!g_getenv ("MONO_ENABLE_LOCK_TRACER"))
+
+       if (!g_hasenv ("MONO_ENABLE_LOCK_TRACER"))
                return;
+
        name = g_strdup_printf ("locks.%d", getpid ());
        trace_file = fopen (name, "w+");
        g_free (name);
index c639bda2efe31db3a121a7354096e9c535b910f2..105655bd1b0b32840a17a5933e2a6a0b283dee87 100644 (file)
@@ -156,7 +156,7 @@ mono_marshal_isinst_with_cache (MonoObject *obj, MonoClass *klass, uintptr_t *ca
 static void init_safe_handle (void);
 
 static void*
-ves_icall_marshal_alloc (gulong size);
+ves_icall_marshal_alloc (gsize size);
 
 void
 mono_string_utf8_to_builder (MonoStringBuilder *sb, char *text);
@@ -332,7 +332,7 @@ mono_marshal_init (void)
                register_icall (mono_ftnptr_to_delegate, "mono_ftnptr_to_delegate", "object ptr ptr", FALSE);
                register_icall (mono_marshal_asany, "mono_marshal_asany", "ptr object int32 int32", FALSE);
                register_icall (mono_marshal_free_asany, "mono_marshal_free_asany", "void object ptr int32 int32", FALSE);
-               register_icall (ves_icall_marshal_alloc, "ves_icall_marshal_alloc", "ptr int32", FALSE);
+               register_icall (ves_icall_marshal_alloc, "ves_icall_marshal_alloc", "ptr ptr", FALSE);
                register_icall (mono_marshal_free, "mono_marshal_free", "void ptr", FALSE);
                register_icall (mono_marshal_set_last_error, "mono_marshal_set_last_error", "void", FALSE);
                register_icall (mono_marshal_set_last_error_windows, "mono_marshal_set_last_error_windows", "void int32", FALSE);
@@ -10678,7 +10678,7 @@ mono_marshal_alloc_co_task_mem (size_t size)
  * mono_marshal_alloc:
  */
 void*
-mono_marshal_alloc (gulong size, MonoError *error)
+mono_marshal_alloc (gsize size, MonoError *error)
 {
        gpointer res;
 
@@ -10693,7 +10693,7 @@ mono_marshal_alloc (gulong size, MonoError *error)
 
 /* This is a JIT icall, it sets the pending exception and returns NULL on error. */
 static void*
-ves_icall_marshal_alloc (gulong size)
+ves_icall_marshal_alloc (gsize size)
 {
        MonoError error;
        void *ret = mono_marshal_alloc (size, &error);
index 3f898dba5a0709d6996a54f9c86c0b370659c111..2469701a84af4650a5e264645394c6b352616e87 100644 (file)
@@ -121,6 +121,7 @@ typedef enum {
        /* Subtypes of MONO_WRAPPER_UNKNOWN */
        WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG,
        WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG,
+       WRAPPER_SUBTYPE_INTERP_IN
 } WrapperSubtype;
 
 typedef struct {
@@ -195,6 +196,10 @@ typedef struct {
        MonoMethod *method;
 } DelegateInvokeWrapperInfo;
 
+typedef struct {
+       MonoMethodSignature *sig;
+} InterpInWrapperInfo;
+
 /*
  * This structure contains additional information to uniquely identify a given wrapper
  * method. It can be retrieved by mono_marshal_get_wrapper_info () for certain types
@@ -237,6 +242,8 @@ typedef struct {
                GsharedvtWrapperInfo gsharedvt;
                /* DELEGATE_INVOKE */
                DelegateInvokeWrapperInfo delegate_invoke;
+               /* INTERP_IN */
+               InterpInWrapperInfo interp_in;
        } d;
 } WrapperInfo;
 
@@ -407,7 +414,7 @@ mono_marshal_unlock_internal (void);
 /* marshaling internal calls */
 
 void * 
-mono_marshal_alloc (gulong size, MonoError *error);
+mono_marshal_alloc (gsize size, MonoError *error);
 
 void 
 mono_marshal_free (gpointer ptr);
index 413d7c40831df779ddf96fb371932d1f9f1dd9c3..e598348f9ba23e0bdd12ccd7ae48bdd79cf8116b 100644 (file)
@@ -163,8 +163,7 @@ mono_parser = {
 
 static GHashTable *config_handlers;
 
-static const char *mono_cfg_dir = NULL;
-static char *mono_cfg_dir_allocated = NULL;
+static char *mono_cfg_dir = NULL;
 
 /* when this interface is stable, export it. */
 typedef struct MonoParseHandler MonoParseHandler;
@@ -473,7 +472,7 @@ mono_config_cleanup (void)
 {
        if (config_handlers)
                g_hash_table_destroy (config_handlers);
-       g_free (mono_cfg_dir_allocated);
+       g_free (mono_cfg_dir);
 }
 
 /* FIXME: error handling */
@@ -661,9 +660,10 @@ mono_config_parse (const char *filename) {
                return;
        }
 
-       home = g_getenv ("MONO_CONFIG");
-       if (home) {
-               mono_config_parse_file (home);
+       // FIXME: leak, do we store any references to home
+       char *env_home = g_getenv ("MONO_CONFIG");
+       if (env_home) {
+               mono_config_parse_file (env_home);
                return;
        }
 
@@ -686,10 +686,12 @@ mono_config_parse (const char *filename) {
 void
 mono_set_config_dir (const char *dir)
 {
-       /* If this variable is set, overrides the directory computed */
-       mono_cfg_dir = g_getenv ("MONO_CFG_DIR");
-       if (mono_cfg_dir == NULL)
-               mono_cfg_dir = mono_cfg_dir_allocated = g_strdup (dir);
+       /* If this environment variable is set, overrides the directory computed */
+       char *env_mono_cfg_dir = g_getenv ("MONO_CFG_DIR");
+       if (env_mono_cfg_dir == NULL && dir != NULL)
+               env_mono_cfg_dir = strdup (dir);
+
+       mono_cfg_dir = env_mono_cfg_dir;
 }
 
 /**
index f2958e964be0ddb76c22b4ff4ebd7574d827c121..a67fc067263ca69b8714b0bb056b9c2fe4028e3d 100644 (file)
@@ -17,7 +17,7 @@
 #include "sgen/sgen-client.h"
 #include "sgen/sgen-cardtable.h"
 #include "sgen/sgen-pinning.h"
-#include "sgen/sgen-thread-pool.h"
+#include "sgen/sgen-workers.h"
 #include "metadata/marshal.h"
 #include "metadata/method-builder.h"
 #include "metadata/abi-details.h"
@@ -2069,7 +2069,7 @@ mono_sgen_register_moved_object (void *obj, void *destination)
         * lock-free data structure for the queue as multiple threads will be
         * adding to it at the same time.
         */
-       if (sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ())) {
+       if (sgen_workers_is_worker_thread (mono_native_thread_id_get ())) {
                sgen_pointer_queue_add (&moved_objects_queue, obj);
                sgen_pointer_queue_add (&moved_objects_queue, destination);
        } else {
@@ -3023,7 +3023,9 @@ mono_gc_base_init (void)
 void
 mono_gc_base_cleanup (void)
 {
-       sgen_thread_pool_shutdown ();
+       sgen_thread_pool_shutdown (major_collector.get_sweep_pool ());
+
+       sgen_workers_shutdown ();
 
        // We should have consumed any outstanding moves.
        g_assert (sgen_pointer_queue_is_empty (&moved_objects_queue));
index 8c1a234616f499e752b71233db8d038245a2debe..fc1de7c25f87aa9759f19d52f0741c0b911fd71f 100644 (file)
@@ -20,7 +20,7 @@
 #include "sgen/sgen-gc.h"
 #include "sgen/sgen-protocol.h"
 #include "sgen/sgen-memory-governor.h"
-#include "sgen/sgen-thread-pool.h"
+#include "sgen/sgen-workers.h"
 #include "metadata/profiler-private.h"
 #include "sgen/sgen-client.h"
 #include "metadata/sgen-bridge-internals.h"
@@ -227,7 +227,8 @@ sgen_is_thread_in_current_stw (SgenThreadInfo *info, int *reason)
        We can't suspend the workers that will do all the heavy lifting.
        FIXME Use some state bit in SgenThreadInfo for this.
        */
-       if (sgen_thread_pool_is_thread_pool_thread (mono_thread_info_get_tid (info))) {
+       if (sgen_thread_pool_is_thread_pool_thread (major_collector.get_sweep_pool (), mono_thread_info_get_tid (info)) ||
+                       sgen_workers_is_worker_thread (mono_thread_info_get_tid (info))) {
                if (reason)
                        *reason = 4;
                return FALSE;
index efff08c45240111f006b7388b90f9eb498258c29..a40ed6de5ea1e62c8c98d1082d18b5f3b919b365 100644 (file)
@@ -546,7 +546,7 @@ initialize (void)
        threadpool_io->updates_size = 0;
 
        threadpool_io->backend = backend_poll;
-       if (g_getenv ("MONO_ENABLE_AIO") != NULL) {
+       if (g_hasenv ("MONO_ENABLE_AIO")) {
 #if defined(HAVE_EPOLL)
                threadpool_io->backend = backend_epoll;
 #elif defined(HAVE_KQUEUE)
index 06aed504381819cb8b07c308a21a7a89493c8466..734b43b41f629ccad056873ed12050c78d9db1a1 100644 (file)
@@ -5078,7 +5078,7 @@ mono_w32file_init (void)
 /*     mono_w32handle_register_capabilities (MONO_W32HANDLE_CONSOLE, */
 /*                                         MONO_W32HANDLE_CAP_WAIT); */
 
-       if (g_getenv ("MONO_STRICT_IO_EMULATION"))
+       if (g_hasenv ("MONO_STRICT_IO_EMULATION"))
                lock_while_writing = TRUE;
 }
 
index 482398288f8e40139c6f997f77069ad163d40f5d..79041633ffaf9d50d6cf372b05fdff33a4272f92 100755 (executable)
@@ -506,7 +506,8 @@ test_sources =                      \
        basic-vectors.cs \
        aot-tests.cs \
        gc-test.cs \
-       gshared.cs
+       gshared.cs \
+       mixed.cs
 
 if NACL_CODEGEN
 test_sources += nacl.cs
@@ -751,6 +752,9 @@ rcheck: mono $(regtests)
 richeck: mono $(regtests)
        $(INTERP_RUNTIME) --regression $(regtests)
 
+mixedcheck: mono mixed.exe
+       $(MINI_RUNTIME) --interp=jit=JitClass mixed.exe
+
 if ARM
 check-seq-points:
 else
index 8cd1999b0857569f330efbad6c882ebc5bd68533..9279967b31afbe1f14bc3e47ee00a9625c7be3c5 100644 (file)
@@ -2356,8 +2356,11 @@ mono_aot_init (void)
 #endif
        mono_counters_register ("Async JIT info size", MONO_COUNTER_INT|MONO_COUNTER_JIT, &async_jit_info_size);
 
-       if (g_getenv ("MONO_LASTAOT"))
-               mono_last_aot_method = atoi (g_getenv ("MONO_LASTAOT"));
+       char *lastaot = g_getenv ("MONO_LASTAOT");
+       if (lastaot) {
+               mono_last_aot_method = atoi (lastaot);
+               g_free (lastaot);
+       }
        aot_cache_init ();
 }
 
index 8cd39fc9b4329a01158cabb7e50620a08e1e4f72..8e3691db62bf3bbadad4e51ba32de3e81b8b3a57 100644 (file)
@@ -883,7 +883,7 @@ mono_debugger_agent_parse_options (char *options)
        char **args, **ptr;
        char *host;
        int port;
-       const char *extra;
+       char *extra;
 
 #ifndef MONO_ARCH_SOFT_DEBUG_SUPPORTED
        fprintf (stderr, "--debugger-agent is not supported on this platform.\n");
@@ -891,8 +891,10 @@ mono_debugger_agent_parse_options (char *options)
 #endif
 
        extra = g_getenv ("MONO_SDB_ENV_OPTIONS");
-       if (extra)
+       if (extra) {
                options = g_strdup_printf ("%s,%s", options, extra);
+               g_free (extra);
+       }
 
        agent_config.enabled = TRUE;
        agent_config.suspend = TRUE;
index 23e576f0ea9046e20cc10366332ac0527ec40f64..1c3060f162477cc8db01fbc0c64c6eb2c6f3ebbb 100644 (file)
@@ -1508,10 +1508,13 @@ mono_decompose_array_access_opts (MonoCompile *cfg)
                                        break;
                                case OP_BOUNDS_CHECK:
                                        MONO_EMIT_NULL_CHECK (cfg, ins->sreg1);
-                                       if (COMPILE_LLVM (cfg))
-                                               MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->flags & MONO_INST_FAULT);
-                                       else
+                                       if (COMPILE_LLVM (cfg)) {
+                                               int index2_reg = alloc_preg (cfg);
+                                               MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, ins->sreg2);
+                                               MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, index2_reg, ins->flags & MONO_INST_FAULT);
+                                       } else {
                                                MONO_ARCH_EMIT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2);
+                                       }
                                        break;
                                case OP_NEWARR:
                                        if (cfg->opt & MONO_OPT_SHARED) {
index 9e09e7a944eb5d7a64fc7f6ef9c1f030ea93ea99..26966768f4038e98dbee439b2f59485b88d0593f 100644 (file)
@@ -1607,7 +1607,7 @@ mono_main (int argc, char* argv[])
        darwin_change_default_file_handles ();
 #endif
 
-       if (g_getenv ("MONO_NO_SMP"))
+       if (g_hasenv ("MONO_NO_SMP"))
                mono_set_use_smp (FALSE);
        
        g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
@@ -1907,9 +1907,18 @@ mono_main (int argc, char* argv[])
 #endif
                } else if (strcmp (argv [i], "--nollvm") == 0){
                        mono_use_llvm = FALSE;
+               } else if ((strcmp (argv [i], "--interpreter") == 0) || !strcmp (argv [i], "--interp")) {
 #ifdef ENABLE_INTERPRETER
-               } else if (strcmp (argv [i], "--interpreter") == 0) {
                        mono_use_interpreter = TRUE;
+#else
+                       fprintf (stderr, "Mono Warning: --interpreter not enabled in this runtime.\n");
+#endif
+               } else if (strncmp (argv [i], "--interp=", 9) == 0) {
+#ifdef ENABLE_INTERPRETER
+                       mono_use_interpreter = TRUE;
+                       mono_interp_parse_options (argv [i] + 9);
+#else
+                       fprintf (stderr, "Mono Warning: --interp= not enabled in this runtime.\n");
 #endif
 
 #ifdef __native_client__
@@ -1969,7 +1978,7 @@ mono_main (int argc, char* argv[])
        }
 #endif
 
-       if (g_getenv ("MONO_XDEBUG"))
+       if (g_hasenv ("MONO_XDEBUG"))
                enable_debugging = TRUE;
 
 #ifdef MONO_CROSS_COMPILE
@@ -2555,10 +2564,11 @@ mono_parse_env_options (int *ref_argc, char **ref_argv [])
 {
        char *ret;
        
-       const char *env_options = g_getenv ("MONO_ENV_OPTIONS");
+       char *env_options = g_getenv ("MONO_ENV_OPTIONS");
        if (env_options == NULL)
                return;
        ret = mono_parse_options_from (env_options, ref_argc, ref_argv);
+       g_free (env_options);
        if (ret == NULL)
                return;
        fprintf (stderr, "%s", ret);
index 4755adbaab1f01f086f98a416846348c5356ca8a..c7b10b3a4c1517217b7c56e798bf9379bced451c 100644 (file)
@@ -2846,6 +2846,72 @@ class Tests
                }
                return 0;
        }
+
+       public class MyException : Exception {
+               public int marker = 0;
+               public string res = "";
+
+               public MyException (String res) {
+                       this.res = res;
+               }
+
+               public bool FilterWithoutState () {
+                       return this.marker == 0x666;
+               }
+
+               public bool FilterWithState () {
+                       bool ret = this.marker == 0x566;
+                       this.marker += 0x100;
+                       return ret;
+               }
+
+               public bool FilterWithStringState () {
+                       bool ret = this.marker == 0x777;
+                       this.res = "fromFilter_" + this.res;
+                       return ret;
+               }
+       }
+
+       public static int test_1_basic_filter_catch () {
+               try {
+                       MyException e = new MyException ("");
+                       e.marker = 0x1337;
+                       throw e;
+               } catch (MyException ex) when (ex.marker == 0x1337) {
+                       return 1;
+               }
+               return 0;
+       }
+
+       public static int test_1234_complicated_filter_catch () {
+               string res = "init";
+               try {
+                       MyException e = new MyException (res);
+                       e.marker = 0x566;
+                       try {
+                               try {
+                                       throw e;
+                               } catch (MyException ex) when (ex.FilterWithoutState ()) {
+                                       res = "WRONG_" + res;
+                               } finally {
+                                       e.marker = 0x777;
+                                       res = "innerFinally_" + res;
+                               }
+                       } catch (MyException ex) when (ex.FilterWithState ()) {
+                               res = "2ndcatch_" + res;
+                       }
+                       // "2ndcatch_innerFinally_init"
+                       // Console.WriteLine ("res1: " + res);
+                       e.res = res;
+                       throw e;
+               } catch (MyException ex) when (ex.FilterWithStringState ()) {
+                       res = "fwos_" + ex.res;
+               } finally {
+                       res = "outerFinally_" + res;
+               }
+               // Console.WriteLine ("res2: " + res);
+               return "outerFinally_fwos_fromFilter_2ndcatch_innerFinally_init" == res ? 1234 : 0;
+       }
 }
 
 #if !__MOBILE__
index d5f9545776ef4c46362d301961cd2b2bbb0a00b3..7f681b23bb5ba355da140cd5fb52c4b0fac81acb 100644 (file)
@@ -145,7 +145,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
 #ifdef HOST_WIN32
        const char *tmp = g_get_tmp_dir ();
 #endif
-       const char *objdump_args = g_getenv ("MONO_OBJDUMP_ARGS");
+       char *objdump_args = g_getenv ("MONO_OBJDUMP_ARGS");
        char *as_file;
        char *o_file;
        char *cmd;
@@ -276,7 +276,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
        unused = system (cmd); 
        g_free (cmd);
        if (!objdump_args)
-               objdump_args = "";
+               objdump_args = g_strdup ("");
 
        fflush (stdout);
 
@@ -293,6 +293,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
        cmd = g_strdup_printf (ARCH_PREFIX DIS_CMD " %s %s", objdump_args, o_file);
        unused = system (cmd);
        g_free (cmd);
+       g_free (objdump_args);
 #else
        g_assert_not_reached ();
 #endif /* HAVE_SYSTEM */
index d1b03b3931b21e42e60353b4c0dbab3051983496..88eac7edb4550f5cfbea080941a36a37afc95da7 100644 (file)
@@ -1247,7 +1247,6 @@ COND:   ldloc.0
        }
 
        .method public static int32 test_1_filters () {
-               .custom instance void [TestDriver]CategoryAttribute::.ctor(string) = ( 01 00 0C 21 49 4E 54 45 52 50 52 45 54 45 52 00 00 )   // ...!INTERPRETER.
                .custom instance void [TestDriver]CategoryAttribute::.ctor(string) = ( 01 00 08 21 42 49 54 43 4F 44 45 00 00 )          // ...!BITCODE..
                .maxstack 16
                .locals init (
index f26e4ff57b3badc3c7a3a9d5c9d91e1d9b3be89a..bda0b457e8520bfd76f4702efef447fe904a9fb0 100644 (file)
@@ -82,6 +82,12 @@ typedef struct _RuntimeMethod
        guint32 *local_offsets;
        unsigned int param_count;
        unsigned int hasthis;
+       gpointer jit_wrapper;
+       gpointer jit_addr;
+       MonoMethodSignature *jit_sig;
+       gpointer jit_entry;
+       MonoType *rtype;
+       MonoType **param_types;
 } RuntimeMethod;
 
 struct _MonoInvocation {
@@ -111,6 +117,7 @@ typedef struct {
 } ThreadContext;
 
 extern int mono_interp_traceopt;
+extern GSList *jit_classes;
 
 MonoException *
 mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *context);
index 5f44592287d9a2d157b9e07002017214d988110a..8d2a26859053f0830db1a8e3416508db811b7a86 100644 (file)
 #endif
 #endif
 
-#define INIT_FRAME(frame,parent_frame,method_args,method_retval,domain,mono_method,error)      \
-       do {    \
-               (frame)->parent = (parent_frame);       \
-               (frame)->stack_args = (method_args);    \
-               (frame)->retval = (method_retval);      \
-               (frame)->runtime_method = mono_interp_get_runtime_method ((domain), (mono_method), (error));    \
-               (frame)->ex = NULL;     \
-               (frame)->ip = NULL;     \
-               (frame)->invoke_trap = 0;       \
+static inline void
+init_frame (MonoInvocation *frame, MonoInvocation *parent_frame, RuntimeMethod *rmethod, stackval *method_args, stackval *method_retval)
+{
+       frame->parent = parent_frame;
+       frame->stack_args = method_args;
+       frame->retval = method_retval;
+       frame->runtime_method = rmethod;
+       frame->ex = NULL;
+       frame->ip = NULL;
+       frame->invoke_trap = 0;
+}
+
+#define INIT_FRAME(frame,parent_frame,method_args,method_retval,domain,mono_method,error) do { \
+       RuntimeMethod *_rmethod = mono_interp_get_runtime_method ((domain), (mono_method), (error));    \
+       init_frame ((frame), (parent_frame), _rmethod, (method_args), (method_retval)); \
        } while (0)
 
+/*
+ * List of classes whose methods will be executed by transitioning to JITted code.
+ * Used for testing.
+ */
+GSList *jit_classes;
+
 void ves_exec_method (MonoInvocation *frame);
 
 static char* dump_stack (stackval *stack, stackval *sp);
@@ -258,18 +270,33 @@ RuntimeMethod*
 mono_interp_get_runtime_method (MonoDomain *domain, MonoMethod *method, MonoError *error)
 {
        RuntimeMethod *rtm;
+       MonoJitDomainInfo *info;
+       MonoMethodSignature *sig;
+       int i;
+
        error_init (error);
 
+       info = domain_jit_info (domain);
        mono_domain_jit_code_hash_lock (domain);
-       if ((rtm = mono_internal_hash_table_lookup (&domain->jit_code_hash, method))) {
-               mono_domain_jit_code_hash_unlock (domain);
+       rtm = mono_internal_hash_table_lookup (&info->interp_code_hash, method);
+       mono_domain_jit_code_hash_unlock (domain);
+       if (rtm)
                return rtm;
-       }
+
+       sig = mono_method_signature (method);
+
        rtm = mono_domain_alloc0 (domain, sizeof (RuntimeMethod));
        rtm->method = method;
-       rtm->param_count = mono_method_signature (method)->param_count;
-       rtm->hasthis = mono_method_signature (method)->hasthis;
-       mono_internal_hash_table_insert (&domain->jit_code_hash, method, rtm);
+       rtm->param_count = sig->param_count;
+       rtm->hasthis = sig->hasthis;
+       rtm->rtype = mini_get_underlying_type (sig->ret);
+       rtm->param_types = mono_domain_alloc0 (domain, sizeof (MonoType*) * sig->param_count);
+       for (i = 0; i < sig->param_count; ++i)
+               rtm->param_types [i] = mini_get_underlying_type (sig->params [i]);
+
+       mono_domain_jit_code_hash_lock (domain);
+       if (!mono_internal_hash_table_lookup (&info->interp_code_hash, method))
+               mono_internal_hash_table_insert (&info->interp_code_hash, method, rtm);
        mono_domain_jit_code_hash_unlock (domain);
 
        return rtm;
@@ -1415,6 +1442,209 @@ handle_enum:
        return retval;
 }
 
+typedef struct {
+       RuntimeMethod *rmethod;
+       gpointer this_arg;
+       gpointer res;
+       gpointer args [16];
+       gpointer *many_args;
+} InterpEntryData;
+
+/* Main function for entering the interpreter from compiled code */
+static void
+interp_entry (InterpEntryData *data)
+{
+       MonoInvocation frame;
+       RuntimeMethod *rmethod = data->rmethod;
+       ThreadContext *context = mono_native_tls_get_value (thread_context_id);
+       ThreadContext context_struct;
+       MonoInvocation *old_frame;
+       stackval result;
+       stackval *args;
+       MonoMethod *method;
+       MonoMethodSignature *sig;
+       MonoType *type;
+       int i;
+
+       method = rmethod->method;
+       sig = mono_method_signature (method);
+
+       // FIXME: Optimize this
+
+       //printf ("%s\n", mono_method_full_name (method, 1));
+
+       frame.ex = NULL;
+       if (context == NULL) {
+               context = &context_struct;
+               memset (context, 0, sizeof (ThreadContext));
+               context_struct.base_frame = &frame;
+               context_struct.env_frame = &frame;
+               mono_native_tls_set_value (thread_context_id, context);
+       }
+       else
+               old_frame = context->current_frame;
+       context->domain = mono_domain_get ();
+
+       args = alloca (sizeof (stackval) * (sig->param_count + (sig->hasthis ? 1 : 0)));
+       if (sig->hasthis)
+               args [0].data.p = data->this_arg;
+
+       gpointer *params;
+       if (data->many_args)
+               params = data->many_args;
+       else
+               params = data->args;
+       for (i = 0; i < sig->param_count; ++i) {
+               int a_index = i + (sig->hasthis ? 1 : 0);
+               if (sig->params [i]->byref) {
+                       args [a_index].data.p = params [i];
+                       continue;
+               }
+               type = rmethod->param_types [i];
+               switch (type->type) {
+               case MONO_TYPE_U1:
+               case MONO_TYPE_I1:
+                       args [a_index].data.i = *(MonoBoolean*)params [i];
+                       break;
+               case MONO_TYPE_U2:
+               case MONO_TYPE_I2:
+                       args [a_index].data.i = *(gint16*)params [i];
+                       break;
+               case MONO_TYPE_U:
+#if SIZEOF_VOID_P == 4
+                       args [a_index].data.p = GINT_TO_POINTER (*(guint32*)params [i]);
+#else
+                       args [a_index].data.p = GINT_TO_POINTER (*(guint64*)params [i]);
+#endif
+                       break;
+               case MONO_TYPE_I:
+#if SIZEOF_VOID_P == 4
+                       args [a_index].data.p = GINT_TO_POINTER (*(gint32*)params [i]);
+#else
+                       args [a_index].data.p = GINT_TO_POINTER (*(gint64*)params [i]);
+#endif
+                       break;
+               case MONO_TYPE_U4:
+                       args [a_index].data.i = *(guint32*)params [i];
+                       break;
+               case MONO_TYPE_I4:
+                       args [a_index].data.i = *(gint32*)params [i];
+                       break;
+               case MONO_TYPE_U8:
+                       args [a_index].data.l = *(guint64*)params [i];
+                       break;
+               case MONO_TYPE_I8:
+                       args [a_index].data.l = *(gint64*)params [i];
+                       break;
+               case MONO_TYPE_PTR:
+               case MONO_TYPE_OBJECT:
+                       args [a_index].data.p = *(MonoObject**)params [i];
+                       break;
+               case MONO_TYPE_VALUETYPE:
+                       args [a_index].data.p = params [i];
+                       break;
+               case MONO_TYPE_GENERICINST:
+                       if (MONO_TYPE_IS_REFERENCE (type))
+                               args [a_index].data.p = params [i];
+                       else
+                               args [a_index].data.vt = params [i];
+                       break;
+               default:
+                       printf ("%s\n", mono_type_full_name (sig->params [i]));
+                       NOT_IMPLEMENTED;
+                       break;
+               }
+       }
+
+       init_frame (&frame, context->current_frame, data->rmethod, args, &result);
+       context->managed_code = 1;
+
+       type = rmethod->rtype;
+       switch (type->type) {
+       case MONO_TYPE_GENERICINST:
+               if (!MONO_TYPE_IS_REFERENCE (type))
+                       frame.retval->data.vt = data->res;
+               break;
+       case MONO_TYPE_VALUETYPE:
+               frame.retval->data.vt = data->res;
+               break;
+       default:
+               break;
+       }
+
+       ves_exec_method_with_context (&frame, context);
+       context->managed_code = 0;
+       if (context == &context_struct)
+               mono_native_tls_set_value (thread_context_id, NULL);
+       else
+               context->current_frame = old_frame;
+
+       // FIXME:
+       g_assert (frame.ex == NULL);
+
+       type = rmethod->rtype;
+       switch (type->type) {
+       case MONO_TYPE_VOID:
+               break;
+       case MONO_TYPE_I1:
+               *(gint8*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_U1:
+               *(guint8*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_I2:
+               *(gint16*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_U2:
+               *(guint16*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_I4:
+               *(gint32*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_U4:
+               *(guint64*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_I8:
+               *(gint64*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_U8:
+               *(guint64*)data->res = frame.retval->data.i;
+               break;
+       case MONO_TYPE_I:
+#if SIZEOF_VOID_P == 8
+               *(gint64*)data->res = (gint64)frame.retval->data.p;
+#else
+               *(gint32*)data->res = (gint32)frame.retval->data.p;
+#endif
+               break;
+       case MONO_TYPE_U:
+#if SIZEOF_VOID_P == 8
+               *(guint64*)data->res = (guint64)frame.retval->data.p;
+#else
+               *(guint32*)data->res = (guint32)frame.retval->data.p;
+#endif
+               break;
+       case MONO_TYPE_OBJECT:
+               /* No need for a write barrier */
+               *(MonoObject**)data->res = (MonoObject*)frame.retval->data.p;
+               break;
+       case MONO_TYPE_GENERICINST:
+               if (MONO_TYPE_IS_REFERENCE (type)) {
+                       *(MonoObject**)data->res = *(MonoObject**)frame.retval->data.p;
+               } else {
+                       /* Already set before the call */
+               }
+               break;
+       case MONO_TYPE_VALUETYPE:
+               /* Already set before the call */
+               break;
+       default:
+               printf ("%s\n", mono_type_full_name (sig->ret));
+               NOT_IMPLEMENTED;
+               break;
+       }
+}
+
 static stackval * 
 do_icall (ThreadContext *context, int op, stackval *sp, gpointer ptr)
 {
@@ -1504,84 +1734,220 @@ do_icall (ThreadContext *context, int op, stackval *sp, gpointer ptr)
        return sp;
 }
 
-static mono_mutex_t create_method_pointer_mutex;
-
-static GHashTable *method_pointer_hash = NULL;
-
-#define TRAMPS_USED 8
-
-static MonoMethod *method_pointers [TRAMPS_USED] = {0};
-
-#define GEN_METHOD_PTR_TRAMP(num) \
-               static MonoObject * mp_tramp_ ## num (MonoObject *this_obj, void **params, MonoObject **exc, void *compiled_method) { \
-                       MonoError error; \
-                       void *params_real[] = {this_obj, &params, &exc, &compiled_method}; \
-                       MonoObject *ret = mono_interp_runtime_invoke (method_pointers [num], NULL, params_real, NULL, &error); \
-                       mono_error_cleanup (&error); \
-                       return ret; \
-               }
-
+/*
+ * These functions are the entry points into the interpreter from compiled code.
+ * They are called by the interp_in wrappers. They have the following signature:
+ * void (<optional this_arg>, <optional retval pointer>, <arg1>, ..., <argn>, <method ptr>)
+ * They pack up their arguments into an InterpEntryData structure and call interp_entry ().
+ * It would be possible for the wrappers to pack up the arguments etc, but that would make them bigger, and there are
+ * more wrappers then these functions.
+ * this/static * ret/void * 16 arguments -> 64 functions.
+ */
 
-GEN_METHOD_PTR_TRAMP (0);
-GEN_METHOD_PTR_TRAMP (1);
-GEN_METHOD_PTR_TRAMP (2);
-GEN_METHOD_PTR_TRAMP (3);
-GEN_METHOD_PTR_TRAMP (4);
-GEN_METHOD_PTR_TRAMP (5);
-GEN_METHOD_PTR_TRAMP (6);
-GEN_METHOD_PTR_TRAMP (7);
+#define MAX_INTERP_ENTRY_ARGS 8
 
-#undef GEN_METHOD_PTR_TRAMP
+#define INTERP_ENTRY_BASE(_method, _this_arg, _res) \
+       InterpEntryData data; \
+       (data).rmethod = (_method); \
+       (data).res = (_res); \
+       (data).this_arg = (_this_arg); \
+       (data).many_args = NULL;
 
-gpointer *mp_tramps[TRAMPS_USED] = {
-       (gpointer) mp_tramp_0, (gpointer) mp_tramp_1, (gpointer) mp_tramp_2, (gpointer) mp_tramp_3,
-       (gpointer) mp_tramp_4, (gpointer) mp_tramp_5, (gpointer) mp_tramp_6, (gpointer) mp_tramp_7
-};
+#define INTERP_ENTRY0(_this_arg, _res, _method) {      \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY1(_this_arg, _res, _method) {        \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY2(_this_arg, _res, _method) {  \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY3(_this_arg, _res, _method) { \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       (data).args [2] = arg3; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY4(_this_arg, _res, _method) {      \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       (data).args [2] = arg3; \
+       (data).args [3] = arg4; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY5(_this_arg, _res, _method) {      \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       (data).args [2] = arg3; \
+       (data).args [3] = arg4; \
+       (data).args [4] = arg5; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY6(_this_arg, _res, _method) {      \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       (data).args [2] = arg3; \
+       (data).args [3] = arg4; \
+       (data).args [4] = arg5; \
+       (data).args [5] = arg6; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY7(_this_arg, _res, _method) {      \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       (data).args [2] = arg3; \
+       (data).args [3] = arg4; \
+       (data).args [4] = arg5; \
+       (data).args [5] = arg6; \
+       (data).args [6] = arg7; \
+       interp_entry (&data); \
+       }
+#define INTERP_ENTRY8(_this_arg, _res, _method) {      \
+       INTERP_ENTRY_BASE (_method, _this_arg, _res); \
+       (data).args [0] = arg1; \
+       (data).args [1] = arg2; \
+       (data).args [2] = arg3; \
+       (data).args [3] = arg4; \
+       (data).args [4] = arg5; \
+       (data).args [5] = arg6; \
+       (data).args [6] = arg7; \
+       (data).args [7] = arg8; \
+       interp_entry (&data); \
+       }
 
-static int tramps_used = 0;
+#define ARGLIST0 RuntimeMethod *rmethod
+#define ARGLIST1 gpointer arg1, RuntimeMethod *rmethod
+#define ARGLIST2 gpointer arg1, gpointer arg2, RuntimeMethod *rmethod
+#define ARGLIST3 gpointer arg1, gpointer arg2, gpointer arg3, RuntimeMethod *rmethod
+#define ARGLIST4 gpointer arg1, gpointer arg2, gpointer arg3, gpointer arg4, RuntimeMethod *rmethod
+#define ARGLIST5 gpointer arg1, gpointer arg2, gpointer arg3, gpointer arg4, gpointer arg5, RuntimeMethod *rmethod
+#define ARGLIST6 gpointer arg1, gpointer arg2, gpointer arg3, gpointer arg4, gpointer arg5, gpointer arg6, RuntimeMethod *rmethod
+#define ARGLIST7 gpointer arg1, gpointer arg2, gpointer arg3, gpointer arg4, gpointer arg5, gpointer arg6, gpointer arg7, RuntimeMethod *rmethod
+#define ARGLIST8 gpointer arg1, gpointer arg2, gpointer arg3, gpointer arg4, gpointer arg5, gpointer arg6, gpointer arg7, gpointer arg8, RuntimeMethod *rmethod
+
+static void interp_entry_static_0 (ARGLIST0) INTERP_ENTRY0 (NULL, NULL, rmethod)
+static void interp_entry_static_1 (ARGLIST1) INTERP_ENTRY1 (NULL, NULL, rmethod)
+static void interp_entry_static_2 (ARGLIST2) INTERP_ENTRY2 (NULL, NULL, rmethod)
+static void interp_entry_static_3 (ARGLIST3) INTERP_ENTRY3 (NULL, NULL, rmethod)
+static void interp_entry_static_4 (ARGLIST4) INTERP_ENTRY4 (NULL, NULL, rmethod)
+static void interp_entry_static_5 (ARGLIST5) INTERP_ENTRY5 (NULL, NULL, rmethod)
+static void interp_entry_static_6 (ARGLIST6) INTERP_ENTRY6 (NULL, NULL, rmethod)
+static void interp_entry_static_7 (ARGLIST7) INTERP_ENTRY7 (NULL, NULL, rmethod)
+static void interp_entry_static_8 (ARGLIST8) INTERP_ENTRY8 (NULL, NULL, rmethod)
+static void interp_entry_static_ret_0 (gpointer res, ARGLIST0) INTERP_ENTRY0 (NULL, res, rmethod)
+static void interp_entry_static_ret_1 (gpointer res, ARGLIST1) INTERP_ENTRY1 (NULL, res, rmethod)
+static void interp_entry_static_ret_2 (gpointer res, ARGLIST2) INTERP_ENTRY2 (NULL, res, rmethod)
+static void interp_entry_static_ret_3 (gpointer res, ARGLIST3) INTERP_ENTRY3 (NULL, res, rmethod)
+static void interp_entry_static_ret_4 (gpointer res, ARGLIST4) INTERP_ENTRY4 (NULL, res, rmethod)
+static void interp_entry_static_ret_5 (gpointer res, ARGLIST5) INTERP_ENTRY5 (NULL, res, rmethod)
+static void interp_entry_static_ret_6 (gpointer res, ARGLIST6) INTERP_ENTRY6 (NULL, res, rmethod)
+static void interp_entry_static_ret_7 (gpointer res, ARGLIST7) INTERP_ENTRY7 (NULL, res, rmethod)
+static void interp_entry_static_ret_8 (gpointer res, ARGLIST8) INTERP_ENTRY8 (NULL, res, rmethod)
+static void interp_entry_instance_0 (gpointer this_arg, ARGLIST0) INTERP_ENTRY0 (this_arg, NULL, rmethod)
+static void interp_entry_instance_1 (gpointer this_arg, ARGLIST1) INTERP_ENTRY1 (this_arg, NULL, rmethod)
+static void interp_entry_instance_2 (gpointer this_arg, ARGLIST2) INTERP_ENTRY2 (this_arg, NULL, rmethod)
+static void interp_entry_instance_3 (gpointer this_arg, ARGLIST3) INTERP_ENTRY3 (this_arg, NULL, rmethod)
+static void interp_entry_instance_4 (gpointer this_arg, ARGLIST4) INTERP_ENTRY4 (this_arg, NULL, rmethod)
+static void interp_entry_instance_5 (gpointer this_arg, ARGLIST5) INTERP_ENTRY5 (this_arg, NULL, rmethod)
+static void interp_entry_instance_6 (gpointer this_arg, ARGLIST6) INTERP_ENTRY6 (this_arg, NULL, rmethod)
+static void interp_entry_instance_7 (gpointer this_arg, ARGLIST7) INTERP_ENTRY7 (this_arg, NULL, rmethod)
+static void interp_entry_instance_8 (gpointer this_arg, ARGLIST8) INTERP_ENTRY8 (this_arg, NULL, rmethod)
+static void interp_entry_instance_ret_0 (gpointer this_arg, gpointer res, ARGLIST0) INTERP_ENTRY0 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_1 (gpointer this_arg, gpointer res, ARGLIST1) INTERP_ENTRY1 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_2 (gpointer this_arg, gpointer res, ARGLIST2) INTERP_ENTRY2 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_3 (gpointer this_arg, gpointer res, ARGLIST3) INTERP_ENTRY3 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_4 (gpointer this_arg, gpointer res, ARGLIST4) INTERP_ENTRY4 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_5 (gpointer this_arg, gpointer res, ARGLIST5) INTERP_ENTRY5 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_6 (gpointer this_arg, gpointer res, ARGLIST6) INTERP_ENTRY6 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_7 (gpointer this_arg, gpointer res, ARGLIST7) INTERP_ENTRY6 (this_arg, res, rmethod)
+static void interp_entry_instance_ret_8 (gpointer this_arg, gpointer res, ARGLIST8) INTERP_ENTRY6 (this_arg, res, rmethod)
+
+#define INTERP_ENTRY_FUNCLIST(type) interp_entry_ ## type ## _0, interp_entry_ ## type ## _1, interp_entry_ ## type ## _2, interp_entry_ ## type ## _3, interp_entry_ ## type ## _4, interp_entry_ ## type ## _5, interp_entry_ ## type ## _6, interp_entry_ ## type ## _7, interp_entry_ ## type ## _8
+
+gpointer entry_funcs_static [MAX_INTERP_ENTRY_ARGS + 1] = { INTERP_ENTRY_FUNCLIST (static) };
+gpointer entry_funcs_static_ret [MAX_INTERP_ENTRY_ARGS + 1] = { INTERP_ENTRY_FUNCLIST (static_ret) };
+gpointer entry_funcs_instance [MAX_INTERP_ENTRY_ARGS + 1] = { INTERP_ENTRY_FUNCLIST (instance) };
+gpointer entry_funcs_instance_ret [MAX_INTERP_ENTRY_ARGS + 1] = { INTERP_ENTRY_FUNCLIST (instance_ret) };
+
+/* General version for methods with more than MAX_INTERP_ENTRY_ARGS arguments */
+static void
+interp_entry_general (gpointer this_arg, gpointer res, gpointer *args, gpointer rmethod)
+{
+       INTERP_ENTRY_BASE (rmethod, this_arg, res);
+       data.many_args = args;
+       interp_entry (&data);
+}
 
+/*
+ * mono_interp_create_method_pointer:
+ *
+ * Return a function pointer which can be used to call METHOD using the
+ * interpreter. Return NULL for methods which are not supported.
+ */
 gpointer
 mono_interp_create_method_pointer (MonoMethod *method, MonoError *error)
 {
        gpointer addr;
-       MonoJitInfo *ji;
+       MonoMethodSignature *sig = mono_method_signature (method);
+       MonoMethod *wrapper;
+       RuntimeMethod *rmethod;
 
-       mono_os_mutex_lock (&create_method_pointer_mutex);
-       if (!method_pointer_hash) {
-               // FIXME: is registering method table as GC root really necessary?
-               // MONO_GC_REGISTER_ROOT_FIXED (method_pointer_hash);
-               method_pointer_hash = g_hash_table_new (NULL, NULL);
-       }
-       addr = g_hash_table_lookup (method_pointer_hash, method);
-       if (addr) {
-               mono_os_mutex_unlock (&create_method_pointer_mutex);
-               return addr;
+       if (method->wrapper_type && method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
+               return NULL;
+
+       rmethod = mono_interp_get_runtime_method (mono_domain_get (), method, error);
+       if (rmethod->jit_entry)
+               return rmethod->jit_entry;
+       wrapper = mini_get_interp_in_wrapper (sig);
+
+       gpointer jit_wrapper = mono_jit_compile_method_jit_only (wrapper, error);
+       mono_error_assert_ok (error);
+
+       //printf ("%s %s\n", mono_method_full_name (method, 1), mono_method_full_name (wrapper, 1));
+       gpointer entry_func;
+       if (sig->param_count > MAX_INTERP_ENTRY_ARGS) {
+               entry_func = interp_entry_general;
+       } else if (sig->hasthis) {
+               if (sig->ret->type == MONO_TYPE_VOID)
+                       entry_func = entry_funcs_instance [sig->param_count];
+               else
+                       entry_func = entry_funcs_instance_ret [sig->param_count];
+       } else {
+               if (sig->ret->type == MONO_TYPE_VOID)
+                       entry_func = entry_funcs_static [sig->param_count];
+               else
+                       entry_func = entry_funcs_static_ret [sig->param_count];
        }
+       g_assert (entry_func);
+
+       /* This is the argument passed to the interp_in wrapper by the static rgctx trampoline */
+       MonoFtnDesc *ftndesc = g_new0 (MonoFtnDesc, 1);
+       ftndesc->addr = entry_func;
+       ftndesc->arg = rmethod;
+       mono_error_assert_ok (error);
 
        /*
-        * If it is a static P/Invoke method, we can just return the pointer
-        * to the method implementation.
+        * The wrapper is called by compiled code, which doesn't pass the extra argument, so we pass it in the
+        * rgctx register using a trampoline.
         */
-       if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL && ((MonoMethodPInvoke*) method)->addr) {
-               ji = g_new0 (MonoJitInfo, 1);
-               ji->d.method = method;
-               ji->code_size = 1;
-               ji->code_start = addr = ((MonoMethodPInvoke*) method)->addr;
-
-               mono_jit_info_table_add (mono_get_root_domain (), ji);
-       }               
-       else {
-               g_assert (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE);
-               g_assert (tramps_used < TRAMPS_USED);
-
-               /* FIXME: needs locking */
-               method_pointers [tramps_used] = method;
-               addr = mp_tramps [tramps_used];
-               tramps_used++;
-       }
 
-       g_hash_table_insert (method_pointer_hash, method, addr);
-       mono_os_mutex_unlock (&create_method_pointer_mutex);
+       // FIXME: AOT
+       g_assert (!mono_aot_only);
+       addr = mono_arch_get_static_rgctx_trampoline (ftndesc, jit_wrapper);
+
+       mono_memory_barrier ();
+       rmethod->jit_entry = addr;
 
        return addr;
 }
@@ -1635,8 +2001,11 @@ static int opcode_counts[512];
 #define MINT_IN_DEFAULT default:
 #endif
 
+static void
+ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context);
+
 static void 
-ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
+ves_exec_method_with_context_with_ip (MonoInvocation *frame, ThreadContext *context, unsigned short *start_with_ip, MonoException *filter_exception)
 {
        MonoInvocation child_frame;
        GSList *finally_ips = NULL;
@@ -1688,25 +2057,26 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
        }
 
        rtm = frame->runtime_method;
-       frame->args = alloca (rtm->alloca_size);
-       memset (frame->args, 0, rtm->alloca_size);
-
-       sp = frame->stack = (stackval *)((char *)frame->args + rtm->args_size);
-       memset (sp, 0, rtm->stack_size);
+       if (!start_with_ip ) {
+               frame->args = alloca (rtm->alloca_size);
+               memset (frame->args, 0, rtm->alloca_size);
 
+               ip = rtm->code;
+       } else {
+               ip = start_with_ip;
+       }
+       sp = frame->stack = (stackval *) ((char *) frame->args + rtm->args_size);
        vt_sp = (unsigned char *) sp + rtm->stack_size;
-       memset (vt_sp, 0, rtm->vt_stack_size);
 #if DEBUG_INTERP
        vtalloc = vt_sp;
 #endif
-
        locals = (unsigned char *) vt_sp + rtm->vt_stack_size;
-       memset (vt_sp, 0, rtm->locals_size);
-
        child_frame.parent = frame;
 
-       /* ready to go */
-       ip = rtm->code;
+       if (filter_exception) {
+               sp->data.p = filter_exception;
+               sp++;
+       }
 
        /*
         * using while (ip < end) may result in a 15% performance drop, 
@@ -1970,6 +2340,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                                child_frame.runtime_method = mono_interp_get_runtime_method (context->domain, mono_marshal_get_remoting_invoke (child_frame.runtime_method->method), &error);
                                mono_error_cleanup (&error); /* FIXME: don't swallow the error */
                        }
+
                        ves_exec_method_with_context (&child_frame, context);
 
                        context->current_frame = frame;
@@ -2023,6 +2394,215 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
                        }
                        MINT_IN_BREAK;
                }
+
+               MINT_IN_CASE(MINT_JIT_CALL) {
+                       MonoMethodSignature *sig;
+                       RuntimeMethod *rmethod = rtm->data_items [* (guint16 *)(ip + 1)];
+                       MonoFtnDesc ftndesc;
+                       guint8 res_buf [256];
+                       MonoType *type;
+
+                       //printf ("%s\n", mono_method_full_name (rmethod->method, 1));
+
+                       /*
+                        * Call JITted code through a gsharedvt_out wrapper. These wrappers receive every argument
+                        * by ref and return a return value using an explicit return value argument.
+                        */
+                       if (!rmethod->jit_wrapper) {
+                               MonoMethod *method = rmethod->method;
+                               MonoError error;
+
+                               sig = mono_method_signature (method);
+                               g_assert (sig);
+
+                               MonoMethod *wrapper = mini_get_gsharedvt_out_sig_wrapper (sig);
+                               //printf ("J: %s %s\n", mono_method_full_name (method, 1), mono_method_full_name (wrapper, 1));
+
+                               gpointer jit_wrapper = mono_jit_compile_method_jit_only (wrapper, &error);
+                               mono_error_assert_ok (&error);
+
+                               gpointer addr = mono_jit_compile_method_jit_only (method, &error);
+                               g_assert (addr);
+                               mono_error_assert_ok (&error);
+
+                               rmethod->jit_addr = addr;
+                               rmethod->jit_sig = sig;
+                               mono_memory_barrier ();
+                               rmethod->jit_wrapper = jit_wrapper;
+
+                       } else {
+                               sig = rmethod->jit_sig;
+                       }
+
+                       frame->ip = ip;
+                       ip += 2;
+                       sp -= sig->param_count;
+                       if (sig->hasthis)
+                               --sp;
+
+                       ftndesc.addr = rmethod->jit_addr;
+                       ftndesc.arg = NULL;
+
+                       // FIXME: Optimize this
+
+                       gpointer args [32];
+                       int pindex = 0;
+                       int stack_index = 0;
+                       if (rmethod->hasthis) {
+                               args [pindex ++] = sp [0].data.p;
+                               stack_index ++;
+                       }
+                       type = rmethod->rtype;
+                       if (type->type != MONO_TYPE_VOID) {
+                               if (MONO_TYPE_ISSTRUCT (type))
+                                       args [pindex ++] = vt_sp;
+                               else
+                                       args [pindex ++] = res_buf;
+                       }
+                       for (int i = 0; i < rmethod->param_count; ++i) {
+                               MonoType *t = rmethod->param_types [i];
+                               stackval *sval = &sp [stack_index + i];
+                               if (sig->params [i]->byref) {
+                                       args [pindex ++] = sval->data.p;
+                               } else if (MONO_TYPE_ISSTRUCT (t)) {
+                                       args [pindex ++] = sval->data.p;
+                               } else if (MONO_TYPE_IS_REFERENCE (t)) {
+                                       args [pindex ++] = &sval->data.p;
+                               } else {
+                                       switch (t->type) {
+                                       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_VALUETYPE:
+                                               args [pindex ++] = &sval->data.i;
+                                               break;
+                                       case MONO_TYPE_PTR:
+                                       case MONO_TYPE_FNPTR:
+                                       case MONO_TYPE_I:
+                                       case MONO_TYPE_U:
+                                       case MONO_TYPE_OBJECT:
+                                               args [pindex ++] = &sval->data.p;
+                                               break;
+                                       case MONO_TYPE_I8:
+                                       case MONO_TYPE_U8:
+                                               args [pindex ++] = &sval->data.l;
+                                               break;
+                                       default:
+                                               printf ("%s\n", mono_type_full_name (t));
+                                               g_assert_not_reached ();
+                                       }
+                               }
+                       }
+
+                       switch (pindex) {
+                       case 0: {
+                               void (*func)(gpointer) = rmethod->jit_wrapper;
+
+                               func (&ftndesc);
+                               break;
+                       }
+                       case 1: {
+                               void (*func)(gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], &ftndesc);
+                               break;
+                       }
+                       case 2: {
+                               void (*func)(gpointer, gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], args [1], &ftndesc);
+                               break;
+                       }
+                       case 3: {
+                               void (*func)(gpointer, gpointer, gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], args [1], args [2], &ftndesc);
+                               break;
+                       }
+                       case 4: {
+                               void (*func)(gpointer, gpointer, gpointer, gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], args [1], args [2], args [3], &ftndesc);
+                               break;
+                       }
+                       case 5: {
+                               void (*func)(gpointer, gpointer, gpointer, gpointer, gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], args [1], args [2], args [3], args [4], &ftndesc);
+                               break;
+                       }
+                       case 6: {
+                               void (*func)(gpointer, gpointer, gpointer, gpointer, gpointer, gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], args [1], args [2], args [3], args [4], args [5], &ftndesc);
+                               break;
+                       }
+                       case 7: {
+                               void (*func)(gpointer, gpointer, gpointer, gpointer, gpointer, gpointer, gpointer, gpointer) = rmethod->jit_wrapper;
+
+                               func (args [0], args [1], args [2], args [3], args [4], args [5], args [6], &ftndesc);
+                               break;
+                       }
+                       default:
+                               g_assert_not_reached ();
+                               break;
+                       }
+
+                       MonoType *rtype = rmethod->rtype;
+                       switch (rtype->type) {
+                       case MONO_TYPE_VOID:
+                       case MONO_TYPE_OBJECT:
+                       case MONO_TYPE_STRING:
+                       case MONO_TYPE_CLASS:
+                       case MONO_TYPE_ARRAY:
+                       case MONO_TYPE_SZARRAY:
+                       case MONO_TYPE_I:
+                       case MONO_TYPE_U:
+                               sp->data.p = *(gpointer*)res_buf;
+                               break;
+                       case MONO_TYPE_I1:
+                               sp->data.i = *(gint8*)res_buf;
+                               break;
+                       case MONO_TYPE_U1:
+                               sp->data.i = *(guint8*)res_buf;
+                               break;
+                       case MONO_TYPE_I2:
+                               sp->data.i = *(gint16*)res_buf;
+                               break;
+                       case MONO_TYPE_U2:
+                               sp->data.i = *(guint16*)res_buf;
+                               break;
+                       case MONO_TYPE_I4:
+                               sp->data.i = *(gint32*)res_buf;
+                               break;
+                       case MONO_TYPE_U4:
+                               sp->data.i = *(guint32*)res_buf;
+                               break;
+                       case MONO_TYPE_VALUETYPE:
+                               /* The result was written to vt_sp */
+                               sp->data.p = vt_sp;
+                               break;
+                       case MONO_TYPE_GENERICINST:
+                               if (MONO_TYPE_IS_REFERENCE (rtype)) {
+                                       sp->data.p = *(gpointer*)res_buf;
+                               } else {
+                                       /* The result was written to vt_sp */
+                                       sp->data.p = vt_sp;
+                               }
+                               break;
+                       default:
+                               printf ("%s\n", mono_type_full_name (rtype));
+                               g_assert_not_reached ();
+                               break;
+                       }
+                       if (rtype->type != MONO_TYPE_VOID)
+                               sp++;
+                       MINT_IN_BREAK;
+               }
+
                MINT_IN_CASE(MINT_CALLVIRT) {
                        stackval *endsp = sp;
                        MonoObject *this_arg;
@@ -3668,6 +4248,9 @@ array_constructed:
                        BINOP_CAST(l, -, guint64);
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_ENDFINALLY)
+                       while (sp > frame->stack) {
+                               --sp;
+                       }
                        if (finally_ips) {
                                ip = finally_ips->data;
                                finally_ips = g_slist_remove (finally_ips, ip);
@@ -3994,9 +4577,10 @@ array_constructed:
                        ++ip;
                        MINT_IN_BREAK;
                }
-#if 0
-               MINT_IN_CASE(MINT_ENDFILTER) ves_abort(); MINT_IN_BREAK;
-#endif
+               MINT_IN_CASE(MINT_ENDFILTER)
+                       /* top of stack is result of filter */
+                       frame->retval = &sp [-1];
+                       goto exit_frame;
                MINT_IN_CASE(MINT_INITOBJ)
                        --sp;
                        memset (sp->data.vt, 0, READ32(ip + 1));
@@ -4093,24 +4677,44 @@ array_constructed:
                        inv->ex_handler = NULL; /* clear this in case we are trhowing an exception while handling one  - this one wins */
                        for (i = 0; i < inv->runtime_method->num_clauses; ++i) {
                                clause = &inv->runtime_method->clauses [i];
-                               if (clause->flags <= 1 && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) {
-                                       if (!clause->flags) {
-                                               MonoObject *isinst_obj = mono_object_isinst_checked ((MonoObject*)frame->ex, clause->data.catch_class, &error);
-                                               mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-                                               if (isinst_obj) {
-                                                       /* 
-                                                        * OK, we found an handler, now we need to execute the finally
-                                                        * and fault blocks before branching to the handler code.
-                                                        */
-                                                       inv->ex_handler = clause;
 #if DEBUG_INTERP
-                                                       if (tracing)
-                                                               g_print ("* Found handler at '%s'\n", method->name);
+                               g_print ("* clause [%d]: %p\n", i, clause);
 #endif
-                                                       goto handle_finally;
-                                               }
-                                       } else {
-                                               g_error ("FIXME: handle filter clause");
+                               if (!MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) {
+                                       continue;
+                               }
+                               if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
+#if DEBUG_INTERP
+                                       if (tracing)
+                                               g_print ("* Filter found at '%s'\n", method->name);
+#endif
+                                       MonoInvocation dup_frame;
+                                       stackval retval;
+                                       memcpy (&dup_frame, inv, sizeof (MonoInvocation));
+                                       dup_frame.retval = &retval;
+                                       ves_exec_method_with_context_with_ip (&dup_frame, context, inv->runtime_method->code + clause->data.filter_offset, frame->ex);
+                                       if (dup_frame.retval->data.i) {
+#if DEBUG_INTERP
+                                               if (tracing)
+                                                       g_print ("* Matched Filter at '%s'\n", method->name);
+#endif
+                                               inv->ex_handler = clause;
+                                               goto handle_finally;
+                                       }
+                               } else if (clause->flags == MONO_EXCEPTION_CLAUSE_NONE) {
+                                       MonoObject *isinst_obj = mono_object_isinst_checked ((MonoObject*)frame->ex, clause->data.catch_class, &error);
+                                       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+                                       if (isinst_obj) {
+                                               /* 
+                                                * OK, we found an handler, now we need to execute the finally
+                                                * and fault blocks before branching to the handler code.
+                                                */
+#if DEBUG_INTERP
+                                               if (tracing)
+                                                       g_print ("* Found handler at '%s'\n", method->name);
+#endif
+                                               inv->ex_handler = clause;
+                                               goto handle_finally;
                                        }
                                }
                        }
@@ -4236,6 +4840,12 @@ exit_frame:
        DEBUG_LEAVE ();
 }
 
+static void
+ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context)
+{
+       ves_exec_method_with_context_with_ip (frame, context, NULL, NULL);
+}
+
 void
 ves_exec_method (MonoInvocation *frame)
 {
@@ -4425,12 +5035,25 @@ interp_ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_fi
        return res;
 }
 
+void
+mono_interp_parse_options (const char *options)
+{
+       char **args, **ptr;
+
+       args = g_strsplit (options, ",", -1);
+       for (ptr = args; ptr && *ptr; ptr ++) {
+               char *arg = *ptr;
+
+               if (strncmp (arg, "jit=", 4) == 0)
+                       jit_classes = g_slist_prepend (jit_classes, arg + 4);
+       }
+}
+
 void
 mono_interp_init ()
 {
        mono_native_tls_alloc (&thread_context_id, NULL);
-    mono_native_tls_set_value (thread_context_id, NULL);
-       mono_os_mutex_init_recursive (&create_method_pointer_mutex);
+       mono_native_tls_set_value (thread_context_id, NULL);
 
        mono_interp_transform_init ();
 }
@@ -4547,6 +5170,7 @@ interp_regression_step (MonoImage *image, int verbose, int *total_run, int *tota
        *total += failed + cfailed;
        *total_run += run;
 }
+
 static int
 interp_regression (MonoImage *image, int verbose, int *total_run)
 {
index 6189b3d1be4e709841609b011a0ec76182cb2b5f..951c47c85e1a416fa8bcbad7e87d0263ccff3228 100644 (file)
@@ -24,6 +24,9 @@ mono_interp_init_delegate (MonoDelegate *del);
 gpointer
 mono_interp_create_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *error);
 
+void
+mono_interp_parse_options (const char *options);
+
 void
 interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUnwindOptions options, void *user_data);
 #endif /* __MONO_MINI_INTERPRETER_H__ */
index a6afa577ebd66786f2dd9b42a27484a140b377c7..39330d479f7eea4098161b4560d21350b6d289db 100644 (file)
@@ -266,6 +266,8 @@ OPDEF(MINT_JMP, "jmp", 2, MintOpMethodToken)
 
 OPDEF(MINT_CALLRUN, "callrun", 1, MintOpNoArgs)
 
+OPDEF(MINT_ENDFILTER, "endfilter", 1, MintOpNoArgs)
+
 OPDEF(MINT_NEWOBJ, "newobj", 2, MintOpMethodToken) 
 OPDEF(MINT_INITOBJ, "initobj", 3, MintOpInt) 
 OPDEF(MINT_CASTCLASS, "castclass", 2, MintOpClassToken) 
@@ -509,4 +511,5 @@ OPDEF(MINT_MONO_NEWOBJ, "mono_newobj", 2, MintOpClassToken)
 OPDEF(MINT_MONO_RETOBJ, "mono_retobj", 1, MintOpNoArgs)
 OPDEF(MINT_MONO_FREE, "mono_free", 1, MintOpNoArgs)
 
-
+// FIXME: MintOp
+OPDEF(MINT_JIT_CALL, "mono_jit_call", 2, MintOpNoArgs)
index 1b1776867fcc1bfe1b585db11a1e008a96c4ea3f..6012bb1e1d78eb1b5b26a0a0972cbecedfebc594 100644 (file)
@@ -636,6 +636,35 @@ get_data_item_index (TransformData *td, void *ptr)
        return index;
 }
 
+static gboolean
+jit_call_supported (MonoMethod *method, MonoMethodSignature *sig)
+{
+       GSList *l;
+
+       if (sig->param_count > 6)
+               return FALSE;
+       if (sig->pinvoke)
+               return FALSE;
+       if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+               return FALSE;
+       if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
+               return FALSE;
+       if (method->is_inflated)
+               return FALSE;
+       if (method->string_ctor)
+               return FALSE;
+
+       for (l = jit_classes; l; l = l->next) {
+               char *class_name = l->data;
+               // FIXME: Namespaces
+               if (!strcmp (method->klass->name, class_name))
+                       return TRUE;
+       }
+
+       //return TRUE;
+       return FALSE;
+}
+
 static void
 interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target_method, MonoDomain *domain, MonoGenericContext *generic_context, unsigned char *is_bb_start, int body_start_offset, MonoClass *constrained_class, gboolean readonly)
 {
@@ -858,6 +887,10 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                        ADD_CODE (td, get_data_item_index (td, target_method->klass));
                        ADD_CODE (td, 1 + target_method->klass->rank);
                }
+       } else if (!calli && !virtual && jit_call_supported (target_method, csignature)) {
+               ADD_CODE(td, MINT_JIT_CALL);
+               ADD_CODE(td, get_data_item_index (td, (void *)mono_interp_get_runtime_method (domain, target_method, &error)));
+               mono_error_assert_ok (&error);
        } else {
                if (calli)
                        ADD_CODE(td, native ? MINT_CALLI_NAT : MINT_CALLI);
@@ -865,7 +898,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                        ADD_CODE(td, is_void ? MINT_VCALLVIRT : MINT_CALLVIRT);
                else
                        ADD_CODE(td, is_void ? MINT_VCALL : MINT_CALL);
-               
+
                if (calli) {
                        ADD_CODE(td, get_data_item_index (td, (void *)csignature));
                } else {
@@ -944,6 +977,17 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                td.stack_state [c->handler_offset] = g_malloc0(sizeof(StackInfo));
                td.stack_state [c->handler_offset][0].type = STACK_TYPE_O;
                td.stack_state [c->handler_offset][0].klass = NULL; /*FIX*/
+
+               if (c->flags & MONO_EXCEPTION_CLAUSE_FILTER) {
+                       td.stack_height [c->data.filter_offset] = 0;
+                       td.vt_stack_size [c->data.filter_offset] = 0;
+                       td.is_bb_start [c->data.filter_offset] = 1;
+
+                       td.stack_height [c->data.filter_offset] = 1;
+                       td.stack_state [c->data.filter_offset] = g_malloc0(sizeof(StackInfo));
+                       td.stack_state [c->data.filter_offset][0].type = STACK_TYPE_O;
+                       td.stack_state [c->data.filter_offset][0].klass = NULL; /*FIX*/
+               }
        }
 
        td.ip = header->code;
@@ -2759,6 +2803,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                        ++td.ip;
                        break;
                case CEE_ENDFINALLY:
+                       td.sp = td.stack;
                        SIMPLE_OP (td, MINT_ENDFINALLY);
                        generating_code = 0;
                        break;
@@ -3072,8 +3117,11 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                break;
 #if 0
                        case CEE_UNUSED57: ves_abort(); break;
-                       case CEE_ENDFILTER: ves_abort(); break;
 #endif
+                       case CEE_ENDFILTER:
+                               ADD_CODE (&td, MINT_ENDFILTER);
+                               ++td.ip;
+                               break;
                        case CEE_UNALIGNED_:
                                ++td.ip;
                                /* FIX: should do something? */;
@@ -3122,6 +3170,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                CHECK_STACK(&td, 3);
                                ADD_CODE(&td, MINT_INITBLK);
                                td.sp -= 3;
+                               td.ip += 1;
                                break;
 #if 0
                        case CEE_NO_:
@@ -3201,6 +3250,8 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                end_off = c->handler_offset + c->handler_len;
                c->handler_offset = td.in_offsets [c->handler_offset];
                c->handler_len = td.in_offsets [end_off] - c->handler_offset;
+               if (c->flags & MONO_EXCEPTION_CLAUSE_FILTER)
+                       c->data.filter_offset = td.in_offsets [c->data.filter_offset];
        }
        rtm->vt_stack_size = td.max_vt_sp;
        rtm->alloca_size = rtm->locals_size + rtm->args_size + rtm->vt_stack_size + rtm->stack_size;
index 859cccd112dac40e219798182f98dc0b5b98dcec..d535f25b6d311f3e566db35914720fb03e133f95 100644 (file)
@@ -813,10 +813,12 @@ static int ccount = 0;
             ins->inst_false_bb = NULL; \
             mono_link_bblock ((cfg), (cfg)->cbb, (truebb)); \
             MONO_ADD_INS ((cfg)->cbb, ins); \
-            if (g_getenv ("COUNT2") && ccount == atoi (g_getenv ("COUNT2")) - 1) { printf ("HIT: %d\n", cfg->cbb->block_num); } \
-            if (g_getenv ("COUNT2") && ccount < atoi (g_getenv ("COUNT2"))) { \
+            char *count2 = g_getenv ("COUNT2"); \
+            if (count2 && ccount == atoi (count2) - 1) { printf ("HIT: %d\n", cfg->cbb->block_num); } \
+            if (count2 && ccount < atoi (count2)) { \
                  cfg->cbb->extended = TRUE; \
             } else { NEW_BBLOCK ((cfg), falsebb); ins->inst_false_bb = (falsebb); mono_link_bblock ((cfg), (cfg)->cbb, (falsebb)); MONO_START_BB ((cfg), falsebb); } \
+            if (count2) g_free (count2); \
         } \
        } while (0)
 #else
index b98c7a57528eb1827e5a95997bcffd63780a8d4f..eaa656e059c1b9c3894a321a9a4d6b19b24704e6 100644 (file)
@@ -857,7 +857,7 @@ mono_analyze_liveness2 (MonoCompile *cfg)
        static guint32 disabled = -1;
 
        if (disabled == -1)
-               disabled = g_getenv ("DISABLED") != NULL;
+               disabled = g_hasenv ("DISABLED");
 
        if (disabled)
                return;
index 868097e617085fc86c9dfb0007a9666922bce742..e10f65766c97c3db26ecd53d7415bbc893ff44c2 100644 (file)
@@ -530,7 +530,11 @@ static void
 force_pass_linking (void)
 {
        // Make sure the rest is linked in, but never executed
-       if (g_getenv ("FOO") != (char*)-1)
+       char *foo = g_getenv ("FOO");
+       gboolean ret = (foo != (char*)-1);
+       g_free (foo);
+
+       if (ret) 
                return;
 
        // This is a subset of the passes in LinkAllPasses.h
index 29e0b1081fec7fd5c65ff23a4b414b61fb2c713d..99a0b10e2d75162342e00f2b53bf713c4ab076e7 100644 (file)
@@ -1261,16 +1261,22 @@ mono_get_got_var (MonoCompile *cfg)
        return cfg->got_var;
 }
 
-static MonoInst *
-mono_get_vtable_var (MonoCompile *cfg)
+static void
+mono_create_rgctx_var (MonoCompile *cfg)
 {
-       g_assert (cfg->gshared);
-
        if (!cfg->rgctx_var) {
                cfg->rgctx_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                /* force the var to be stack allocated */
                cfg->rgctx_var->flags |= MONO_INST_VOLATILE;
        }
+}
+
+static MonoInst *
+mono_get_vtable_var (MonoCompile *cfg)
+{
+       g_assert (cfg->gshared);
+
+       mono_create_rgctx_var (cfg);
 
        return cfg->rgctx_var;
 }
@@ -3002,11 +3008,18 @@ emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
                wbarrier->sreg1 = ptr->dreg;
                wbarrier->sreg2 = value->dreg;
                MONO_ADD_INS (cfg->cbb, wbarrier);
-       } else if (card_table && !cfg->compile_aot && !mono_gc_card_table_nursery_check ()) {
+       } else if (card_table) {
                int offset_reg = alloc_preg (cfg);
                int card_reg;
                MonoInst *ins;
 
+               /*
+                * We emit a fast light weight write barrier. This always marks cards as in the concurrent
+                * collector case, so, for the serial collector, it might slightly slow down nursery
+                * collections. We also expect that the host system and the target system have the same card
+                * table configuration, which is the case if they have the same pointer size.
+                */
+
                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SHR_UN_IMM, offset_reg, ptr->dreg, card_table_shift_bits);
                if (card_table_mask)
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_PAND_IMM, offset_reg, offset_reg, card_table_mask);
@@ -3281,6 +3294,16 @@ emit_get_rgctx (MonoCompile *cfg, MonoMethod *method, int context_used)
                mrgctx_loc = mono_get_vtable_var (cfg);
                EMIT_NEW_TEMPLOAD (cfg, mrgctx_var, mrgctx_loc->inst_c0);
 
+               return mrgctx_var;
+       } else if (MONO_CLASS_IS_INTERFACE (cfg->method->klass)) {
+               MonoInst *mrgctx_loc, *mrgctx_var;
+
+               /* Default interface methods need an mrgctx since the vtabke at runtime points at an implementing class */
+               mrgctx_loc = mono_get_vtable_var (cfg);
+               EMIT_NEW_TEMPLOAD (cfg, mrgctx_var, mrgctx_loc->inst_c0);
+
+               g_assert (mono_method_needs_static_rgctx_invoke (cfg->method, TRUE));
+
                return mrgctx_var;
        } else if (method->flags & METHOD_ATTRIBUTE_STATIC || method->klass->valuetype) {
                MonoInst *vtable_loc, *vtable_var;
@@ -4579,9 +4602,11 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
        /* also consider num_locals? */
        /* Do the size check early to avoid creating vtables */
        if (!inline_limit_inited) {
-               if (g_getenv ("MONO_INLINELIMIT"))
-                       inline_limit = atoi (g_getenv ("MONO_INLINELIMIT"));
-               else
+               char *inlinelimit;
+               if ((inlinelimit = g_getenv ("MONO_INLINELIMIT"))) {
+                       inline_limit = atoi (inlinelimit);
+                       g_free (inlinelimit);
+               } else
                        inline_limit = INLINE_LENGTH_LIMIT;
                inline_limit_inited = TRUE;
        }
@@ -4715,7 +4740,11 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono
 #if SIZEOF_REGISTER == 8
        /* The array reg is 64 bits but the index reg is only 32 */
        if (COMPILE_LLVM (cfg)) {
-               /* Not needed */
+               /*
+                * abcrem can't handle the OP_SEXT_I4, so add this after abcrem,
+                * during OP_BOUNDS_CHECK decomposition, and in the implementation
+                * of OP_X86_LEA for llvm.
+                */
                index2_reg = index_reg;
        } else {
                index2_reg = alloc_preg (cfg);
@@ -12340,6 +12369,21 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                ins->type = STACK_I4;
                                MONO_ADD_INS (cfg->cbb, ins);
 
+                               ip += 2;
+                               *sp++ = ins;
+                               break;
+                       case CEE_MONO_GET_RGCTX_ARG:
+                               CHECK_OPSIZE (2);
+                               CHECK_STACK_OVF (1);
+
+                               mono_create_rgctx_var (cfg);
+
+                               MONO_INST_NEW (cfg, ins, OP_MOVE);
+                               ins->dreg = alloc_dreg (cfg, STACK_PTR);
+                               ins->sreg1 = cfg->rgctx_var->dreg;
+                               ins->type = STACK_PTR;
+                               MONO_ADD_INS (cfg->cbb, ins);
+
                                ip += 2;
                                *sp++ = ins;
                                break;
index 658311340e14b515b538477422c0ade899bbcf71..f80d5f5b0272e5f6315be7c26c65cf5941b91f7c 100644 (file)
@@ -812,6 +812,7 @@ mono_arch_init (void)
 
        if (soft && !strncmp (soft, "1", 1))
                arm_fpu = MONO_ARM_FPU_NONE;
+       g_free (soft);
 #endif
 #endif
 
@@ -859,6 +860,7 @@ mono_arch_init (void)
 
                thumb_supported = strstr (cpu_arch, "thumb") != NULL;
                thumb2_supported = strstr (cpu_arch, "thumb2") != NULL;
+               g_free (cpu_arch);
        }
 }
 
index 14bd722aca127a552c040e3981bad1c77974822a..8aeb6ffb2f48e88b4a227ad352ad2b78a995d54c 100644 (file)
@@ -62,7 +62,7 @@ mono_cross_helpers_run (void)
 #endif
 
 #ifndef USED_CROSS_COMPILER_OFFSETS
-       if (g_getenv ("DUMP_CROSS_OFFSETS"))
+       if (g_hasenv ("DUMP_CROSS_OFFSETS"))
                mono_dump_jit_offsets ();
 #endif
        
index 31e775ecc9e5c7f004307a52a8ba1d897d5a0c53..3b5463e80fb1c16626c54ad26547553a3fbee682 100644 (file)
@@ -925,8 +925,11 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                 * Debugging aid to control the number of frames scanned precisely
                 */
                if (!precise_frame_limit_inited) {
-                       if (g_getenv ("MONO_PRECISE_COUNT"))
-                               precise_frame_limit = atoi (g_getenv ("MONO_PRECISE_COUNT"));
+                       char *mono_precise_count = g_getenv ("MONO_PRECISE_COUNT");
+                       if (mono_precise_count) {
+                               precise_frame_limit = atoi (mono_precise_count);
+                               g_free (mono_precise_count);
+                       }
                        precise_frame_limit_inited = TRUE;
                }
                                
@@ -1281,10 +1284,13 @@ mini_gc_init_gc_map (MonoCompile *cfg)
                static int precise_count;
 
                precise_count ++;
-               if (g_getenv ("MONO_GCMAP_COUNT")) {
-                       if (precise_count == atoi (g_getenv ("MONO_GCMAP_COUNT")))
+               char *mono_gcmap_count = g_getenv ("MONO_GCMAP_COUNT");
+               if (mono_gcmap_count) {
+                       int count = atoi (mono_gcmap_count);
+                       g_free (mono_gcmap_count);
+                       if (precise_count == count)
                                printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
-                       if (precise_count > atoi (g_getenv ("MONO_GCMAP_COUNT")))
+                       if (precise_count > count)
                                return;
                }
        }
@@ -2504,6 +2510,7 @@ parse_debug_options (void)
                exit (1);
        }
        g_strfreev (opts);
+       g_free (env);
 }
 
 void
index deeee74524e350dc6737772a58167528c70ea6c2..587d368a4186ce564c123e0969c783d24a0fe667 100644 (file)
@@ -1200,9 +1200,9 @@ mini_get_gsharedvt_in_sig_wrapper (MonoMethodSignature *sig)
        sig = mini_get_underlying_signature (sig);
 
        // FIXME: Normal cache
+       gshared_lock ();
        if (!cache)
                cache = g_hash_table_new_full ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal, NULL, NULL);
-       gshared_lock ();
        res = g_hash_table_lookup (cache, sig);
        gshared_unlock ();
        if (res) {
@@ -1304,9 +1304,9 @@ mini_get_gsharedvt_out_sig_wrapper (MonoMethodSignature *sig)
        sig = mini_get_underlying_signature (sig);
 
        // FIXME: Normal cache
+       gshared_lock ();
        if (!cache)
                cache = g_hash_table_new_full ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal, NULL, NULL);
-       gshared_lock ();
        res = g_hash_table_lookup (cache, sig);
        gshared_unlock ();
        if (res) {
@@ -1408,6 +1408,170 @@ mini_get_gsharedvt_out_sig_wrapper (MonoMethodSignature *sig)
        return res;
 }
 
+/*
+ * mini_get_interp_in_wrapper:
+ *
+ *   Return a wrapper which can be used to transition from compiled code to the interpreter.
+ * The wrapper has the same signature as SIG. It is very similar to a gsharedvt_in wrapper,
+ * except the 'extra_arg' is passed in the rgctx reg, so this wrapper needs to be
+ * called through a static rgctx trampoline.
+ * FIXME: Move this elsewhere.
+ */
+MonoMethod*
+mini_get_interp_in_wrapper (MonoMethodSignature *sig)
+{
+       MonoMethodBuilder *mb;
+       MonoMethod *res, *cached;
+       WrapperInfo *info;
+       MonoMethodSignature *csig, *entry_sig;
+       int i, pindex, retval_var = 0;
+       static GHashTable *cache;
+       const char *name;
+       gboolean generic = FALSE;
+
+       sig = mini_get_underlying_signature (sig);
+
+       gshared_lock ();
+       if (!cache)
+               cache = g_hash_table_new_full ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal, NULL, NULL);
+       res = g_hash_table_lookup (cache, sig);
+       gshared_unlock ();
+       if (res) {
+               g_free (sig);
+               return res;
+       }
+
+       if (sig->param_count > 8)
+               /* Call the generic interpreter entry point, the specialized ones only handle a limited number of arguments */
+               generic = TRUE;
+
+       /* Create the signature for the wrapper */
+       csig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + (sig->param_count * sizeof (MonoType*)));
+       memcpy (csig, sig, mono_metadata_signature_size (sig));
+
+       /* Create the signature for the callee callconv */
+       if (generic) {
+               /*
+                * The called function has the following signature:
+                * interp_entry_general (gpointer this_arg, gpointer res, gpointer *args, gpointer rmethod)
+                */
+               entry_sig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + (4 * sizeof (MonoType*)));
+               entry_sig->ret = &mono_defaults.void_class->byval_arg;
+               entry_sig->param_count = 4;
+               entry_sig->params [0] = &mono_defaults.int_class->byval_arg;
+               entry_sig->params [1] = &mono_defaults.int_class->byval_arg;
+               entry_sig->params [2] = &mono_defaults.int_class->byval_arg;
+               entry_sig->params [3] = &mono_defaults.int_class->byval_arg;
+               name = "interp_in_generic";
+               generic = TRUE;
+       } else  {
+               /*
+                * The called function has the following signature:
+                * void entry(<optional this ptr>, <optional return ptr>, <arguments>, <extra arg>)
+                */
+               entry_sig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((sig->param_count + 2) * sizeof (MonoType*)));
+               memcpy (entry_sig, sig, mono_metadata_signature_size (sig));
+               pindex = 0;
+               /* The return value is returned using an explicit vret argument */
+               if (sig->ret->type != MONO_TYPE_VOID) {
+                       entry_sig->params [pindex ++] = &mono_defaults.int_class->byval_arg;
+                       entry_sig->ret = &mono_defaults.void_class->byval_arg;
+               }
+               for (i = 0; i < sig->param_count; i++) {
+                       entry_sig->params [pindex] = sig->params [i];
+                       if (!sig->params [i]->byref) {
+                               entry_sig->params [pindex] = mono_metadata_type_dup (NULL, entry_sig->params [pindex]);
+                               entry_sig->params [pindex]->byref = 1;
+                       }
+                       pindex ++;
+               }
+               /* Extra arg */
+               entry_sig->params [pindex ++] = &mono_defaults.int_class->byval_arg;
+               entry_sig->param_count = pindex;
+               name = sig->hasthis ? "interp_in" : "interp_in_static";
+       }
+
+       mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_UNKNOWN);
+
+       // FIXME: save lmf
+
+#ifndef DISABLE_JIT
+       if (sig->ret->type != MONO_TYPE_VOID)
+               retval_var = mono_mb_add_local (mb, sig->ret);
+
+       /* Make the call */
+       if (generic) {
+               /* Collect arguments */
+               int args_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+
+               mono_mb_emit_icon (mb, sizeof (gpointer) * sig->param_count);
+               mono_mb_emit_byte (mb, CEE_PREFIX1);
+               mono_mb_emit_byte (mb, CEE_LOCALLOC);
+               mono_mb_emit_stloc (mb, args_var);
+
+               for (i = 0; i < sig->param_count; i++) {
+                       mono_mb_emit_ldloc (mb, args_var);
+                       mono_mb_emit_icon (mb, sizeof (gpointer) * i);
+                       mono_mb_emit_byte (mb, CEE_ADD);
+                       if (sig->params [i]->byref)
+                               mono_mb_emit_ldarg (mb, i + (sig->hasthis == TRUE));
+                       else
+                               mono_mb_emit_ldarg_addr (mb, i + (sig->hasthis == TRUE));
+                       mono_mb_emit_byte (mb, CEE_STIND_I);
+               }
+
+               if (sig->hasthis)
+                       mono_mb_emit_ldarg (mb, 0);
+               else
+                       mono_mb_emit_byte (mb, CEE_LDNULL);
+               if (sig->ret->type != MONO_TYPE_VOID)
+                       mono_mb_emit_ldloc_addr (mb, retval_var);
+               else
+                       mono_mb_emit_byte (mb, CEE_LDNULL);
+               mono_mb_emit_ldloc (mb, args_var);
+       } else {
+               if (sig->hasthis)
+                       mono_mb_emit_ldarg (mb, 0);
+               if (sig->ret->type != MONO_TYPE_VOID)
+                       mono_mb_emit_ldloc_addr (mb, retval_var);
+               for (i = 0; i < sig->param_count; i++) {
+                       if (sig->params [i]->byref)
+                               mono_mb_emit_ldarg (mb, i + (sig->hasthis == TRUE));
+                       else
+                               mono_mb_emit_ldarg_addr (mb, i + (sig->hasthis == TRUE));
+               }
+       }
+       /* Extra arg */
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_GET_RGCTX_ARG);
+       mono_mb_emit_icon (mb, sizeof (gpointer));
+       mono_mb_emit_byte (mb, CEE_ADD);
+       mono_mb_emit_byte (mb, CEE_LDIND_I);
+       /* Method to call */
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_GET_RGCTX_ARG);
+       mono_mb_emit_byte (mb, CEE_LDIND_I);
+       mono_mb_emit_calli (mb, entry_sig);
+       if (sig->ret->type != MONO_TYPE_VOID)
+               mono_mb_emit_ldloc (mb, retval_var);
+       mono_mb_emit_byte (mb, CEE_RET);
+#endif
+
+       info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_INTERP_IN);
+       info->d.interp_in.sig = sig;
+
+       res = mono_mb_create (mb, csig, sig->param_count + 16, info);
+
+       gshared_lock ();
+       cached = g_hash_table_lookup (cache, sig);
+       if (cached)
+               res = cached;
+       else
+               g_hash_table_insert (cache, sig, res);
+       gshared_unlock ();
+       return res;
+}
+
 MonoMethodSignature*
 mini_get_gsharedvt_out_sig_wrapper_signature (gboolean has_this, gboolean has_ret, int param_count)
 {
@@ -2852,7 +3016,8 @@ mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_v
                return TRUE;
 
        return ((method->flags & METHOD_ATTRIBUTE_STATIC) ||
-                       method->klass->valuetype) &&
+                       method->klass->valuetype ||
+                       MONO_CLASS_IS_INTERFACE (method->klass)) &&
                (mono_class_is_ginst (method->klass) || mono_class_is_gtd (method->klass));
 }
 
index b3517ab58aa0abeb7af420553c95d8459bd15d28..b53dafd323ea81108323fcb26d7cda53573525ae 100644 (file)
@@ -4985,6 +4985,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_X86_LEA: {
                        LLVMValueRef v1, v2;
 
+                       rhs = LLVMBuildSExt (builder, convert (ctx, rhs, LLVMInt32Type ()), LLVMInt64Type (), "");
+
                        v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
                        v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
                        values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
@@ -6930,13 +6932,16 @@ emit_method_inner (EmitContext *ctx)
                static int count = 0;
                count ++;
 
-               if (g_getenv ("LLVM_COUNT")) {
-                       if (count == atoi (g_getenv ("LLVM_COUNT"))) {
+               char *llvm_count_str = g_getenv ("LLVM_COUNT");
+               if (llvm_count_str) {
+                       int lcount = atoi (llvm_count_str);
+                       g_free (llvm_count_str);
+                       if (count == lcount) {
                                printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
                                fflush (stdout);
                                last = TRUE;
                        }
-                       if (count > atoi (g_getenv ("LLVM_COUNT"))) {
+                       if (count > lcount) {
                                set_failure (ctx, "count");
                                return;
                        }
index 9b404ff7c1c3b384c616b20f3b368bab1b514441..aaa6ddda3ecf8a2310758f067c1a1eaa89911693 100644 (file)
@@ -369,18 +369,18 @@ void mono_ppc_set_func_into_sigctx (void *sigctx, void *func);
 #ifdef DEBUG_ELFABIV2
 
 #define DEBUG_ELFABIV2_printf(a, ...) \
-{if (getenv("DEBUG_ELFABIV2")) { printf(a, ##__VA_ARGS__); fflush(stdout); } }
+{char *debug_env; if (debug_env = getenv("DEBUG_ELFABIV2")) { printf(a, ##__VA_ARGS__); fflush(stdout); g_free (debug_env); } }
 
 #define DEBUG_ELFABIV2_mono_print_ins(a) \
-{if (getenv("DEBUG_ELFABIV2")) { if (!a) {printf("null\n");} else {mono_print_ins(a);} fflush(stdout); } }
+{char *debug_env; if (debug_env = getenv("DEBUG_ELFABIV2")) { if (!a) {printf("null\n");} else {mono_print_ins(a);} fflush(stdout); g_free (debug_env); } }
 
 extern char* mono_type_full_name (MonoType *type);
 
 #define DEBUG_ELFABIV2_mono_print_type(a) \
-{if (getenv("DEBUG_ELFABIV2")) { printf("%s, size: %d\n", mono_type_get_name(a), mini_type_stack_size (a, 0)); fflush(stdout); } }
+{char *debug_env; if (debug_env = getenv("DEBUG_ELFABIV2")) { printf("%s, size: %d\n", mono_type_get_name(a), mini_type_stack_size (a, 0)); fflush(stdout); g_free (debug_env); } }
 
 #define DEBUG_ELFABIV2_mono_print_class(a) \
-{if (getenv("DEBUG_ELFABIV2")) { printf("%s\n", mono_type_get_name(&a->byval_arg)); fflush(stdout); } }
+{char *debug_env; if (debug_env = getenv("DEBUG_ELFABIV2")) { printf("%s\n", mono_type_get_name(&a->byval_arg)); fflush(stdout); g_free (debug_env); } }
 
 #else
 
index d8f22a99a33a17c5c41ae535a11d63334045cc5c..190af5cec63edf4eb598a5d9811ec21587a59e26 100644 (file)
@@ -568,7 +568,7 @@ mono_debug_count (void)
 {
        static int count = 0;
        static gboolean inited;
-       static const char *value;
+       static char *value;
 
        count ++;
 
@@ -580,10 +580,13 @@ mono_debug_count (void)
        if (!value)
                return TRUE;
 
-       if (count == atoi (value))
+       int int_val = atoi (value);
+       g_free (value);
+
+       if (count == int_val)
                break_count ();
 
-       if (count > atoi (value))
+       if (count > int_val)
                return FALSE;
 
        return TRUE;
@@ -1751,7 +1754,7 @@ no_gsharedvt_in_wrapper (void)
 }
 
 static gpointer
-mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *error)
+mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, gboolean jit_only, MonoError *error)
 {
        MonoDomain *target_domain, *domain = mono_domain_get ();
        MonoJitInfo *info;
@@ -1763,8 +1766,11 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er
        error_init (error);
 
 #ifdef ENABLE_INTERPRETER
-       if (mono_use_interpreter)
-               return mono_interp_create_method_pointer (method, error);
+       if (mono_use_interpreter && !jit_only) {
+               code = mono_interp_create_method_pointer (method, error);
+               if (code)
+                       return code;
+       }
 #endif
 
        if (mono_llvm_only)
@@ -1921,7 +1927,21 @@ mono_jit_compile_method (MonoMethod *method, MonoError *error)
 {
        gpointer code;
 
-       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), error);
+       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), FALSE, error);
+       return code;
+}
+
+/*
+ * mono_jit_compile_method_jit_only:
+ *
+ *   Compile METHOD using the JIT/AOT, even in interpreted mode.
+ */
+gpointer
+mono_jit_compile_method_jit_only (MonoMethod *method, MonoError *error)
+{
+       gpointer code;
+
+       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), TRUE, error);
        return code;
 }
 
@@ -2408,7 +2428,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                }
 
                if (callee) {
-                       compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), error);
+                       compiled_method = mono_jit_compile_method (callee, error);
                        if (!compiled_method) {
                                g_assert (!mono_error_ok (error));
                                return NULL;
@@ -3191,13 +3211,14 @@ mini_parse_debug_option (const char *option)
 static void
 mini_parse_debug_options (void)
 {
-       const char *options = g_getenv ("MONO_DEBUG");
+       char *options = g_getenv ("MONO_DEBUG");
        gchar **args, **ptr;
 
        if (!options)
                return;
 
        args = g_strsplit (options, ",", -1);
+       g_free (options);
 
        for (ptr = args; ptr && *ptr; ptr++) {
                const char *arg = *ptr;
@@ -3354,6 +3375,7 @@ mini_create_jit_domain_info (MonoDomain *domain)
        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);
+       mono_jit_code_hash_init (&info->interp_code_hash);
 
        domain->runtime_info = info;
 }
@@ -3586,8 +3608,9 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_threads_runtime_init (&ticallbacks);
 
-       if (g_getenv ("MONO_DEBUG") != NULL)
+       if (g_hasenv ("MONO_DEBUG")) {
                mini_parse_debug_options ();
+       }
 
        mono_code_manager_init ();
 
@@ -3606,15 +3629,16 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_unwind_init ();
 
-       if (mini_get_debug_options ()->lldb || g_getenv ("MONO_LLDB")) {
+       if (mini_get_debug_options ()->lldb || g_hasenv ("MONO_LLDB")) {
                mono_lldb_init ("");
                mono_dont_free_domains = TRUE;
        }
 
 #ifdef XDEBUG_ENABLED
-       if (g_getenv ("MONO_XDEBUG")) {
-               const char *xdebug_opts = g_getenv ("MONO_XDEBUG");
-               mono_xdebug_init (xdebug_opts);
+       char *mono_xdebug = g_getenv ("MONO_XDEBUG");
+       if (mono_xdebug) {
+               mono_xdebug_init (mono_xdebug);
+               g_free (mono_xdebug);
                /* So methods for multiple domains don't have the same address */
                mono_dont_free_domains = TRUE;
                mono_using_xdebug = TRUE;
index 4a03047c8b33cbb4e6f2c72477ce3a7ceb66bf23..1afbca76287e9cf3ebdd5fc52803f6a01c91292e 100644 (file)
@@ -5505,13 +5505,16 @@ mono_arch_is_inst_imm (gint64 imm)
 void
 mono_arch_finish_init (void)
 {
-       if (!g_getenv ("MONO_NO_TLS")) {
+       char *mono_no_tls = g_getenv ("MONO_NO_TLS");
+       if (!mono_no_tls) {
 #ifndef TARGET_WIN32
 #if MONO_XEN_OPT
                optimize_for_xen = access ("/proc/xen", F_OK) == 0;
 #endif
 #endif
-       }               
+       } else {
+               g_free (mono_no_tls);
+       }
 }
 
 void
index e5503e27d34eda01528da1feeb022e497edfc0d5..c81919ececada46517dc824b89e7a60219885640 100644 (file)
@@ -3114,7 +3114,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        gboolean llvm = (flags & JIT_FLAG_LLVM) ? 1 : 0;
 #endif
        static gboolean verbose_method_inited;
-       static const char *verbose_method_name;
+       static char *verbose_method_name;
 
        InterlockedIncrement (&mono_jit_stats.methods_compiled);
        if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION)
index c84e5290d463a693676b0e0f99bd1b5957283732..730c936de3c6a5103683ada79fe930cabdc9cb7c 100644 (file)
@@ -366,6 +366,8 @@ typedef struct
        gpointer llvm_module;
        /* Maps MonoMethod -> GSlist of addresses */
        GHashTable *llvm_jit_callees;
+       /* Maps MonoMethod -> RuntimeMethod */
+       MonoInternalHashTable interp_code_hash;
 } MonoJitDomainInfo;
 
 typedef struct {
@@ -2420,6 +2422,7 @@ gpointer  mono_resolve_patch_target         (MonoMethod *method, MonoDomain *dom
 gpointer  mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *method, MonoJitInfo **ji);
 gpointer  mono_jit_find_compiled_method     (MonoDomain *domain, MonoMethod *method);
 gpointer  mono_jit_compile_method           (MonoMethod *method, MonoError *error);
+gpointer  mono_jit_compile_method_jit_only  (MonoMethod *method, MonoError *error);
 gpointer  mono_jit_compile_method_inner     (MonoMethod *method, MonoDomain *target_domain, int opt, MonoError *error);
 MonoLMF * mono_get_lmf                      (void);
 MonoLMF** mono_get_lmf_addr                 (void);
@@ -3098,6 +3101,7 @@ MonoMethod* mini_get_gsharedvt_in_sig_wrapper (MonoMethodSignature *sig);
 MonoMethod* mini_get_gsharedvt_out_sig_wrapper (MonoMethodSignature *sig);
 MonoMethodSignature* mini_get_gsharedvt_out_sig_wrapper_signature (gboolean has_this, gboolean has_ret, int param_count);
 gboolean mini_gsharedvt_runtime_invoke_supported (MonoMethodSignature *sig);
+MonoMethod* mini_get_interp_in_wrapper (MonoMethodSignature *sig);
 
 /* SIMD support */
 
diff --git a/mono/mini/mixed.cs b/mono/mini/mixed.cs
new file mode 100644 (file)
index 0000000..be88673
--- /dev/null
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+/*
+ * Regression tests for the mixed-mode execution.
+ * Run with --interp=jit=JitClass
+ */
+
+struct AStruct {
+       public int i;
+}
+
+struct GStruct<T> {
+       public int i;
+}
+
+class InterpClass
+{
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void entry_void_0 () {
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static int entry_int_int (int i) {
+               return i + 1;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public int entry_int_this_int (int i) {
+               return i + 1;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static string entry_string_string (string s1, string s2) {
+               return s1 + s2;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static AStruct entry_struct_struct (AStruct l) {
+               return l;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static List<string> entry_ginst_ginst (List<string> l) {
+               return l;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static GStruct<string> entry_ginst_ginst_vtype (GStruct<string> l) {
+               return l;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void entry_void_byref_int (ref int i) {
+               i = i + 1;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static int entry_8_int_args (int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8) {
+               return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static int entry_9_int_args (int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9) {
+               return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static IntPtr entry_intptr_intptr (IntPtr i) {
+               return i;
+       }
+
+}
+
+/* The methods in this class will always be JITted */
+class JitClass
+{
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static int entry () {
+               InterpClass.entry_void_0 ();
+               InterpClass.entry_void_0 ();
+               int res = InterpClass.entry_int_int (1);
+               if (res != 2)
+                       return 1;
+               var c = new InterpClass ();
+               res = c.entry_int_this_int (1);
+               if (res != 2)
+                       return 2;
+               var s = InterpClass.entry_string_string ("A", "B");
+               if (s != "AB")
+                       return 3;
+               var astruct = new AStruct () { i = 1 };
+               var astruct2 = InterpClass.entry_struct_struct (astruct);
+               if (astruct2.i != 1)
+                       return 4;
+               var l = new List<string> ();
+               var l2 = InterpClass.entry_ginst_ginst (l);
+               if (l != l2)
+                       return 5;
+               var gstruct = new GStruct<string> () { i = 1 };
+               var gstruct2 = InterpClass.entry_ginst_ginst_vtype (gstruct);
+               if (gstruct2.i != 1)
+                       return 6;
+               int val = 1;
+               InterpClass.entry_void_byref_int (ref val);
+               if (val != 2)
+                       return 7;
+               res = InterpClass.entry_8_int_args (1, 2, 3, 4, 5, 6, 7, 8);
+               if (res != 36)
+                       return 8;
+               res = InterpClass.entry_9_int_args (1, 2, 3, 4, 5, 6, 7, 8, 9);
+               if (res != 45)
+                       return 9;
+               var ptr = new IntPtr (32);
+               var ptr2 = InterpClass.entry_intptr_intptr (ptr);
+               if (ptr != ptr2)
+                       return 10;
+               return 0;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static AStruct exit_vtype (AStruct s) {
+               return s;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static List<string> exit_ginst (List<string> l) {
+               return l;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static GStruct<string> exit_ginst_vtype (GStruct<string> l) {
+               return l;
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void exit_byref (ref int i) {
+               i += 1;
+       }
+}
+
+#if __MOBILE__
+class MixedTests
+#else
+class Tests
+#endif
+{
+
+#if !__MOBILE__
+       public static int Main (string[] args) {
+               return TestDriver.RunTests (typeof (Tests), args);
+       }
+#endif
+
+       public static int test_0_entry () {
+               // This does an interp->jit transition
+               return JitClass.entry ();
+       }
+
+       public static int test_0_exit () {
+               var astruct = new AStruct () { i = 1};
+               var astruct2 = JitClass.exit_vtype (astruct);
+               if (astruct2.i != 1)
+                       return 1;
+               var ginst = new List<string> ();
+               var ginst2 = JitClass.exit_ginst (ginst);
+               if (ginst != ginst2)
+                       return 2;
+               var gstruct = new GStruct<string> () { i = 1 };
+               var gstruct2 = JitClass.exit_ginst_vtype (gstruct);
+               if (gstruct2.i != 1)
+                       return 3;
+               var anint = 1;
+               JitClass.exit_byref (ref anint);
+               if (anint != 2)
+                       return 4;
+               return 0;
+       }
+}
\ No newline at end of file
index 21fd43e7d437f0ed5689d9d63c455e19add2be50..d8a7edd6dd8483d3628e9f99d80ab45bed0d35d6 100644 (file)
@@ -639,6 +639,7 @@ class Tests {
        public static int test_0_vector_array_cast () {
                Array arr1 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0});
                Array arr2 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {10});
+               Array arr5 = Array.CreateInstance (typeof (string), new int[] {1}, new int[] {10});
 
                if (arr1.GetType () != typeof (int[]))
                        return 1;
@@ -659,6 +660,9 @@ class Tests {
 
                if (arr2 is int[])
                        return 4;
+               var as_object_arr = arr5 as object [];
+               if (as_object_arr != null)
+                       return 5;
 
                int [,] [] arr3 = new int [1, 1] [];
                object o = arr3;
index db3c5b960901e0bb4ef9f73fad5f762bd514896c..aa61977cd8f0395c40dedd758282a9acd35e72f1 100644 (file)
@@ -1015,9 +1015,10 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
        static int farg_regs[] = {AMD64_XMM0, AMD64_XMM1, AMD64_XMM2};
-       int i, framesize = 0, off_rbp, off_methodargs, off_targetaddr;
+       int buf_len, i, framesize = 0, off_rbp, off_methodargs, off_targetaddr;
 
-       start = code = (guint8 *) mono_global_codeman_reserve (256 + MONO_TRAMPOLINE_UNWINDINFO_SIZE(0));
+       buf_len = 512 + MONO_TRAMPOLINE_UNWINDINFO_SIZE(0);
+       start = code = (guint8 *) mono_global_codeman_reserve (buf_len);
 
        off_rbp = -framesize;
 
@@ -1056,9 +1057,8 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
                amd64_dec_reg_size (code, AMD64_RAX, 1);
        }
 
-       for (i = 0; i < fregs_num; i++) {
+       for (i = 0; i < fregs_num; i++)
                x86_patch (label_fexits [i], code);
-       }
 
        /* load pointer to MethodArguments* into R11 */
        amd64_mov_reg_reg (code, AMD64_R11, AMD64_ARG_REG2, sizeof (mgreg_t));
@@ -1086,9 +1086,8 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
                amd64_dec_reg_size (code, AMD64_RAX, 1);
        }
 
-       for (i = 0; i < gregs_num; i++) {
+       for (i = 0; i < gregs_num; i++)
                x86_patch (label_gexits [i], code);
-       }
 
        /* load target addr */
        amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_targetaddr, sizeof (mgreg_t));
@@ -1108,8 +1107,6 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        label_is_float_ret = code;
        x86_branch8 (code, X86_CC_NZ, 0, FALSE);
 
-
-
        /* greg return */
        /* load MethodArguments */
        amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
@@ -1125,8 +1122,6 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        label_leave_tramp [1] = code;
        x86_jump8 (code, 0);
 
-
-
        /* freg return */
        x86_patch (label_is_float_ret, code);
        /* load MethodArguments */
@@ -1147,6 +1142,8 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        amd64_pop_reg (code, AMD64_RBP);
        amd64_ret (code);
 
+       g_assert (code - start < buf_len);
+
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
 
index fa684925a78c6b04ff6a262e65717227b8c5c60b..0e67d3d63c613675eadd855c134d887d123e9e3c 100644 (file)
@@ -127,7 +127,7 @@ mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
 
        addr = mono_get_addr_from_ftnptr (addr);
 
-       /* Compute size of code needed to emit mrgctx */
+       /* Compute size of code needed to emit the arg */
        p = imm_buf;
        ppc_load_ptr (p, MONO_ARCH_RGCTX_REG, arg);
        imm_size = p - imm_buf;
@@ -141,12 +141,12 @@ mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
        mono_domain_unlock (domain);
 
        if (short_branch) {
-               ppc_load_ptr (code, MONO_ARCH_RGCTX_REG, mrgctx);
+               ppc_load_ptr (code, MONO_ARCH_RGCTX_REG, arg);
                ppc_emit32 (code, short_branch);
        } else {
                ppc_load_ptr (code, ppc_r0, addr);
                ppc_mtctr (code, ppc_r0);
-               ppc_load_ptr (code, MONO_ARCH_RGCTX_REG, mrgctx);
+               ppc_load_ptr (code, MONO_ARCH_RGCTX_REG, arg);
                ppc_bcctr (code, 20, 0);
        }
        mono_arch_flush_icache (start, code - start);
index 812c430a634225259b2e584fda24a70789eb26df..96a03d97ffbf9d63bbea80a0bb3c8a06fbeb1bf3 100644 (file)
@@ -665,6 +665,14 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        int rank_reg = alloc_preg (cfg);
                        int eclass_reg = alloc_preg (cfg);
 
+                       if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
+                               /* Check that the object is a vector too */
+                               int bounds_reg = alloc_preg (cfg);
+                               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, obj_reg, MONO_STRUCT_OFFSET (MonoArray, bounds));
+                               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0);
+                               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
+                       }
+
                        g_assert (!context_used);
                        MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, rank));
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, rank_reg, klass->rank);
@@ -687,14 +695,6 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        } else if (mono_class_is_interface (klass->cast_class)) {
                                mini_emit_iface_class_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        } else {
-                               if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
-                                       /* Check that the object is a vector too */
-                                       int bounds_reg = alloc_preg (cfg);
-                                       MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, obj_reg, MONO_STRUCT_OFFSET (MonoArray, bounds));
-                                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0);
-                                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
-                               }
-
                                /* the is_null_bb target simply copies the input register to the output */
                                mini_emit_isninst_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        }
index b4b2751e34a872615453c3bb2ffa1629d256b534..3a7500e0b1247d4ad4a40b7a421a1c19832716d3 100644 (file)
@@ -4932,7 +4932,7 @@ mono_profiler_startup (const char *desc)
                if ((opt = match_option (p, "coverage", NULL)) != p) {
                        do_coverage = 1;
                        events |= MONO_PROFILE_ENTER_LEAVE;
-                       debug_coverage = (g_getenv ("MONO_PROFILER_DEBUG_COVERAGE") != NULL);
+                       debug_coverage = g_hasenv ("MONO_PROFILER_DEBUG_COVERAGE");
                        continue;
                }
                if ((opt = match_option (p, "onlycoverage", NULL)) != p) {
index 42a9101b1d66eb591e57be26164b5454e1dbe46f..a1fac4ada5da4a212f1f63b2fb19e7cbbf072216 100644 (file)
@@ -49,13 +49,6 @@ guint64 remarked_cards;
 static guint64 large_objects;
 static guint64 bloby_objects;
 #endif
-static guint64 major_card_scan_time;
-static guint64 los_card_scan_time;
-
-static guint64 last_major_scan_time;
-static guint64 last_los_scan_time;
-
-static void sgen_card_tables_collect_stats (gboolean begin);
 
 mword
 sgen_card_table_number_of_cards_in_range (mword address, mword size)
@@ -417,19 +410,8 @@ sgen_card_table_clear_cards (void)
 }
 
 static void
-sgen_card_table_finish_minor_collection (void)
-{
-       sgen_card_tables_collect_stats (FALSE);
-}
-
-static void
-sgen_card_table_scan_remsets (ScanCopyContext ctx)
+sgen_card_table_start_scan_remsets (void)
 {
-       SGEN_TV_DECLARE (atv);
-       SGEN_TV_DECLARE (btv);
-
-       sgen_card_tables_collect_stats (TRUE);
-
 #ifdef SGEN_HAVE_OVERLAPPING_CARDS
        /*FIXME we should have a bit on each block/los object telling if the object have marked cards.*/
        /*First we copy*/
@@ -440,17 +422,6 @@ sgen_card_table_scan_remsets (ScanCopyContext ctx)
        /*Then we clear*/
        sgen_card_table_clear_cards ();
 #endif
-       SGEN_TV_GETTIME (atv);
-       sgen_get_major_collector ()->scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, 0, 1);
-       SGEN_TV_GETTIME (btv);
-       last_major_scan_time = SGEN_TV_ELAPSED (atv, btv); 
-       major_card_scan_time += last_major_scan_time;
-       sgen_los_scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, 0, 1);
-       SGEN_TV_GETTIME (atv);
-       last_los_scan_time = SGEN_TV_ELAPSED (btv, atv);
-       los_card_scan_time += last_los_scan_time;
-
-       sgen_wbroots_scan_card_table (ctx);
 }
 
 guint8*
@@ -573,69 +544,6 @@ sgen_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *cards,
        binary_protocol_card_scan (obj, sgen_safe_object_get_size (obj));
 }
 
-#ifdef CARDTABLE_STATS
-
-typedef struct {
-       int total, marked, remarked, gc_marked; 
-} card_stats;
-
-static card_stats major_stats, los_stats;
-static card_stats *cur_stats;
-
-static void
-count_marked_cards (mword start, mword size)
-{
-       mword end = start + size;
-       while (start <= end) {
-               guint8 card = *sgen_card_table_get_card_address (start);
-               ++cur_stats->total;
-               if (card)
-                       ++cur_stats->marked;
-               if (card == 2)
-                       ++cur_stats->gc_marked;
-               start += CARD_SIZE_IN_BYTES;
-       }
-}
-
-static void
-count_remarked_cards (mword start, mword size)
-{
-       mword end = start + size;
-       while (start <= end) {
-               if (sgen_card_table_address_is_marked (start)) {
-                       ++cur_stats->remarked;
-                       *sgen_card_table_get_card_address (start) = 2;
-               }
-               start += CARD_SIZE_IN_BYTES;
-       }
-}
-
-#endif
-
-static void
-sgen_card_tables_collect_stats (gboolean begin)
-{
-#ifdef CARDTABLE_STATS
-       if (begin) {
-               memset (&major_stats, 0, sizeof (card_stats));
-               memset (&los_stats, 0, sizeof (card_stats));
-               cur_stats = &major_stats;
-               sgen_major_collector_iterate_live_block_ranges (count_marked_cards);
-               cur_stats = &los_stats;
-               sgen_los_iterate_live_block_ranges (count_marked_cards);
-       } else {
-               cur_stats = &major_stats;
-               sgen_major_collector_iterate_live_block_ranges (count_remarked_cards);
-               cur_stats = &los_stats;
-               sgen_los_iterate_live_block_ranges (count_remarked_cards);
-               printf ("cards major (t %d m %d g %d r %d)  los (t %d m %d g %d r %d) major_scan %.2fms los_scan %.2fms\n", 
-                       major_stats.total, major_stats.marked, major_stats.gc_marked, major_stats.remarked,
-                       los_stats.total, los_stats.marked, los_stats.gc_marked, los_stats.remarked,
-                       last_major_scan_time / 10000.0f, last_los_scan_time / 10000.0f);
-       }
-#endif
-}
-
 void
 sgen_card_table_init (SgenRememberedSet *remset)
 {
@@ -654,9 +562,6 @@ sgen_card_table_init (SgenRememberedSet *remset)
        mono_counters_register ("cardtable large objects", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &large_objects);
        mono_counters_register ("cardtable bloby objects", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &bloby_objects);
 #endif
-       mono_counters_register ("cardtable major scan time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &major_card_scan_time);
-       mono_counters_register ("cardtable los scan time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &los_card_scan_time);
-
 
        remset->wbarrier_set_field = sgen_card_table_wbarrier_set_field;
        remset->wbarrier_arrayref_copy = sgen_card_table_wbarrier_arrayref_copy;
@@ -665,9 +570,8 @@ sgen_card_table_init (SgenRememberedSet *remset)
        remset->wbarrier_generic_nostore = sgen_card_table_wbarrier_generic_nostore;
        remset->record_pointer = sgen_card_table_record_pointer;
 
-       remset->scan_remsets = sgen_card_table_scan_remsets;
+       remset->start_scan_remsets = sgen_card_table_start_scan_remsets;
 
-       remset->finish_minor_collection = sgen_card_table_finish_minor_collection;
        remset->clear_cards = sgen_card_table_clear_cards;
 
        remset->find_address = sgen_card_table_find_address;
index 1e3d3918b65ce7187ff5a09ff6a9f7e4223cdfe3..925af17275dd67a1d2606d0c302b1ba3d7a4c38b 100644 (file)
@@ -124,6 +124,12 @@ copy_object_no_checks_par (GCObject *obj, SgenGrayQueue *queue)
                                GRAY_OBJECT_ENQUEUE_PARALLEL (queue, (GCObject *)destination, sgen_vtable_get_descriptor (vt));
                        }
                } else {
+                       /*
+                        * Unlikely case. Clear the allocated object so it doesn't confuse nursery
+                        * card table scanning, since it can contain old invalid refs.
+                        * FIXME make sure it is not a problem if another threads scans it while we clear
+                        */
+                       mono_gc_bzero_aligned (destination, objsize);
                        destination = final_destination;
                }
        }
index f6aad7eeb37f624f7c2acdda4bd8630b3a8a72b5..e30fb2d48090214a16fb1259298b8e4946bdcd13 100644 (file)
@@ -268,6 +268,8 @@ static guint64 stat_pinned_objects = 0;
 static guint64 time_minor_pre_collection_fragment_clear = 0;
 static guint64 time_minor_pinning = 0;
 static guint64 time_minor_scan_remsets = 0;
+static guint64 time_minor_scan_major_blocks = 0;
+static guint64 time_minor_scan_los = 0;
 static guint64 time_minor_scan_pinned = 0;
 static guint64 time_minor_scan_roots = 0;
 static guint64 time_minor_finish_gray_stack = 0;
@@ -427,8 +429,6 @@ sgen_workers_get_job_gray_queue (WorkerData *worker_data, SgenGrayQueue *default
 static void
 gray_queue_redirect (SgenGrayQueue *queue)
 {
-       SGEN_ASSERT (0, concurrent_collection_in_progress, "Where are we redirecting the gray queue to, without a concurrent collection?");
-
        sgen_workers_take_from_queue (queue);
 }
 
@@ -1234,6 +1234,8 @@ init_stats (void)
        mono_counters_register ("Minor fragment clear", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_pre_collection_fragment_clear);
        mono_counters_register ("Minor pinning", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_pinning);
        mono_counters_register ("Minor scan remembered set", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_scan_remsets);
+       mono_counters_register ("Minor scan major blocks", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_scan_major_blocks);
+       mono_counters_register ("Minor scan los", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_scan_los);
        mono_counters_register ("Minor scan pinned", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_scan_pinned);
        mono_counters_register ("Minor scan roots", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_scan_roots);
        mono_counters_register ("Minor fragment creation", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &time_minor_fragment_creation);
@@ -1334,12 +1336,6 @@ scan_copy_context_for_scan_job (void *worker_data_untyped, ScanJob *job)
        return CONTEXT_FROM_OBJECT_OPERATIONS (job->ops, sgen_workers_get_job_gray_queue (worker_data, job->gc_thread_gray_queue));
 }
 
-static void
-job_remembered_set_scan (void *worker_data_untyped, SgenThreadPoolJob *job)
-{
-       remset.scan_remsets (scan_copy_context_for_scan_job (worker_data_untyped, (ScanJob*)job));
-}
-
 typedef struct {
        ScanJob scan_job;
        char *heap_start;
@@ -1385,6 +1381,43 @@ job_scan_finalizer_entries (void *worker_data_untyped, SgenThreadPoolJob *job)
        scan_finalizer_entries (job_data->queue, ctx);
 }
 
+static void
+job_scan_wbroots (void *worker_data_untyped, SgenThreadPoolJob *job)
+{
+       ScanJob *job_data = (ScanJob*)job;
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
+
+       sgen_wbroots_scan_card_table (ctx);
+}
+
+static void
+job_scan_major_card_table (void *worker_data_untyped, SgenThreadPoolJob *job)
+{
+       SGEN_TV_DECLARE (atv);
+       SGEN_TV_DECLARE (btv);
+       ParallelScanJob *job_data = (ParallelScanJob*)job;
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, (ScanJob*)job_data);
+
+       SGEN_TV_GETTIME (atv);
+       major_collector.scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, job_data->job_index, sgen_workers_get_job_split_count ());
+       SGEN_TV_GETTIME (btv);
+       time_minor_scan_major_blocks += SGEN_TV_ELAPSED (atv, btv);
+}
+
+static void
+job_scan_los_card_table (void *worker_data_untyped, SgenThreadPoolJob *job)
+{
+       SGEN_TV_DECLARE (atv);
+       SGEN_TV_DECLARE (btv);
+       ParallelScanJob *job_data = (ParallelScanJob*)job;
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, (ScanJob*)job_data);
+
+       SGEN_TV_GETTIME (atv);
+       sgen_los_scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, job_data->job_index, sgen_workers_get_job_split_count ());
+       SGEN_TV_GETTIME (btv);
+       time_minor_scan_los += SGEN_TV_ELAPSED (atv, btv);
+}
+
 static void
 job_scan_major_mod_union_card_table (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
@@ -1476,6 +1509,34 @@ init_gray_queue (SgenGrayQueue *gc_thread_gray_queue, gboolean use_workers)
        sgen_gray_object_queue_init (gc_thread_gray_queue, NULL, TRUE);
 }
 
+static void
+enqueue_scan_remembered_set_jobs (SgenGrayQueue *gc_thread_gray_queue, SgenObjectOperations *ops, gboolean enqueue)
+{
+       int i, split_count = sgen_workers_get_job_split_count ();
+       ScanJob *sj;
+
+       sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan wbroots", job_scan_wbroots, sizeof (ScanJob));
+       sj->ops = ops;
+       sj->gc_thread_gray_queue = gc_thread_gray_queue;
+       sgen_workers_enqueue_job (&sj->job, enqueue);
+
+       for (i = 0; i < split_count; i++) {
+               ParallelScanJob *psj;
+
+               psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("scan major remsets", job_scan_major_card_table, sizeof (ParallelScanJob));
+               psj->scan_job.ops = ops;
+               psj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
+               psj->job_index = i;
+               sgen_workers_enqueue_job (&psj->scan_job.job, enqueue);
+
+               psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("scan LOS remsets", job_scan_los_card_table, sizeof (ParallelScanJob));
+               psj->scan_job.ops = ops;
+               psj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
+               psj->job_index = i;
+               sgen_workers_enqueue_job (&psj->scan_job.job, enqueue);
+       }
+}
+
 static void
 enqueue_scan_from_roots_jobs (SgenGrayQueue *gc_thread_gray_queue, char *heap_start, char *heap_end, SgenObjectOperations *ops, gboolean enqueue)
 {
@@ -1536,13 +1597,12 @@ enqueue_scan_from_roots_jobs (SgenGrayQueue *gc_thread_gray_queue, char *heap_st
 static gboolean
 collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_queue)
 {
-       gboolean needs_major;
+       gboolean needs_major, is_parallel = FALSE;
        size_t max_garbage_amount;
        char *nursery_next;
        mword fragment_total;
-       ScanJob *sj;
        SgenGrayQueue gc_thread_gray_queue;
-       SgenObjectOperations *object_ops;
+       SgenObjectOperations *object_ops_nopar, *object_ops_par = NULL;
        ScanCopyContext ctx;
        TV_DECLARE (atv);
        TV_DECLARE (btv);
@@ -1557,10 +1617,16 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
 
        binary_protocol_collection_begin (gc_stats.minor_gc_count, GENERATION_NURSERY);
 
-       if (sgen_concurrent_collection_in_progress ())
-               object_ops = &sgen_minor_collector.serial_ops_with_concurrent_major;
-       else
-               object_ops = &sgen_minor_collector.serial_ops;
+       if (sgen_concurrent_collection_in_progress ()) {
+               /* FIXME Support parallel nursery collections with concurrent major */
+               object_ops_nopar = &sgen_minor_collector.serial_ops_with_concurrent_major;
+       } else {
+               object_ops_nopar = &sgen_minor_collector.serial_ops;
+               if (sgen_minor_collector.is_parallel) {
+                       object_ops_par = &sgen_minor_collector.parallel_ops;
+                       is_parallel = TRUE;
+               }
+       }
 
        if (do_verify_nursery || do_dump_nursery_content)
                sgen_debug_verify_nursery (do_dump_nursery_content);
@@ -1597,8 +1663,8 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
 
        sgen_memgov_minor_collection_start ();
 
-       init_gray_queue (&gc_thread_gray_queue, FALSE);
-       ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, &gc_thread_gray_queue);
+       init_gray_queue (&gc_thread_gray_queue, is_parallel);
+       ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops_nopar, &gc_thread_gray_queue);
 
        gc_stats.minor_gc_count ++;
 
@@ -1630,10 +1696,9 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
        SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (btv, atv));
        SGEN_LOG (4, "Start scan with %zd pinned objects", sgen_get_pinned_count ());
 
-       sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan remset", job_remembered_set_scan, sizeof (ScanJob));
-       sj->ops = object_ops;
-       sj->gc_thread_gray_queue = &gc_thread_gray_queue;
-       sgen_workers_enqueue_job (&sj->job, FALSE);
+       remset.start_scan_remsets ();
+
+       enqueue_scan_remembered_set_jobs (&gc_thread_gray_queue, is_parallel ? object_ops_par : object_ops_nopar, is_parallel);
 
        /* we don't have complete write barrier yet, so we scan all the old generation sections */
        TV_GETTIME (btv);
@@ -1648,7 +1713,13 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
        TV_GETTIME (atv);
        time_minor_scan_pinned += TV_ELAPSED (btv, atv);
 
-       enqueue_scan_from_roots_jobs (&gc_thread_gray_queue, sgen_get_nursery_start (), nursery_next, object_ops, FALSE);
+       enqueue_scan_from_roots_jobs (&gc_thread_gray_queue, sgen_get_nursery_start (), nursery_next, is_parallel ? object_ops_par : object_ops_nopar, is_parallel);
+
+       if (is_parallel) {
+               gray_queue_redirect (&gc_thread_gray_queue);
+               sgen_workers_start_all_workers (object_ops_nopar, object_ops_par, NULL);
+               sgen_workers_join ();
+       }
 
        TV_GETTIME (btv);
        time_minor_scan_roots += TV_ELAPSED (atv, btv);
@@ -1710,8 +1781,6 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
 
        sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
 
-       remset.finish_minor_collection ();
-
        check_scan_starts ();
 
        binary_protocol_flush_buffers (FALSE);
@@ -1868,7 +1937,8 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_
 
        SGEN_ASSERT (0, sgen_workers_all_done (), "Why are the workers not done when we start or finish a major collection?");
        if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
-               sgen_workers_set_num_active_workers (0);
+               if (object_ops_par != NULL)
+                       sgen_workers_set_num_active_workers (0);
                if (sgen_workers_have_idle_work ()) {
                        /*
                         * We force the finish of the worker with the new object ops context
@@ -1913,8 +1983,11 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_
 
        if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
                int i, split_count = sgen_workers_get_job_split_count ();
+               gboolean parallel = object_ops_par != NULL;
 
-               gray_queue_redirect (gc_thread_gray_queue);
+               /* If we're not parallel we finish the collection on the gc thread */
+               if (parallel)
+                       gray_queue_redirect (gc_thread_gray_queue);
 
                /* Mod union card table */
                for (i = 0; i < split_count; i++) {
@@ -1922,27 +1995,29 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_
 
                        psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("scan mod union cardtable", job_scan_major_mod_union_card_table, sizeof (ParallelScanJob));
                        psj->scan_job.ops = object_ops_par ? object_ops_par : object_ops_nopar;
-                       psj->scan_job.gc_thread_gray_queue = NULL;
+                       psj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
                        psj->job_index = i;
-                       sgen_workers_enqueue_job (&psj->scan_job.job, TRUE);
+                       sgen_workers_enqueue_job (&psj->scan_job.job, parallel);
 
                        psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("scan LOS mod union cardtable", job_scan_los_mod_union_card_table, sizeof (ParallelScanJob));
                        psj->scan_job.ops = object_ops_par ? object_ops_par : object_ops_nopar;
-                       psj->scan_job.gc_thread_gray_queue = NULL;
+                       psj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
                        psj->job_index = i;
-                       sgen_workers_enqueue_job (&psj->scan_job.job, TRUE);
+                       sgen_workers_enqueue_job (&psj->scan_job.job, parallel);
                }
 
-               /*
-                * If we enqueue a job while workers are running we need to sgen_workers_ensure_awake
-                * in order to make sure that we are running the idle func and draining all worker
-                * gray queues. The operation of starting workers implies this, so we start them after
-                * in order to avoid doing this operation twice. The workers will drain the main gray
-                * stack that contained roots and pinned objects and also scan the mod union card
-                * table.
-                */
-               sgen_workers_start_all_workers (object_ops_nopar, object_ops_par, NULL);
-               sgen_workers_join ();
+               if (parallel) {
+                       /*
+                        * If we enqueue a job while workers are running we need to sgen_workers_ensure_awake
+                        * in order to make sure that we are running the idle func and draining all worker
+                        * gray queues. The operation of starting workers implies this, so we start them after
+                        * in order to avoid doing this operation twice. The workers will drain the main gray
+                        * stack that contained roots and pinned objects and also scan the mod union card
+                        * table.
+                        */
+                       sgen_workers_start_all_workers (object_ops_nopar, object_ops_par, NULL);
+                       sgen_workers_join ();
+               }
        }
 
        sgen_pin_stats_report ();
@@ -2925,7 +3000,7 @@ parse_double_in_interval (const char *env_var, const char *opt_name, const char
 void
 sgen_gc_init (void)
 {
-       const char *env;
+       char *env;
        char **opts, **ptr;
        char *major_collector_opt = NULL;
        char *minor_collector_opt = NULL;
@@ -2970,6 +3045,7 @@ sgen_gc_init (void)
 
        if ((env = g_getenv (MONO_GC_PARAMS_NAME)) || gc_params_options) {
                params_opts = g_strdup_printf ("%s,%s", gc_params_options ? gc_params_options : "", env ? env : "");
+               g_free (env);
        }
 
        if (params_opts) {
@@ -3004,11 +3080,13 @@ sgen_gc_init (void)
        sgen_client_init ();
 
        if (!minor_collector_opt) {
-               sgen_simple_nursery_init (&sgen_minor_collector);
+               sgen_simple_nursery_init (&sgen_minor_collector, FALSE);
        } else {
                if (!strcmp (minor_collector_opt, "simple")) {
                use_simple_nursery:
-                       sgen_simple_nursery_init (&sgen_minor_collector);
+                       sgen_simple_nursery_init (&sgen_minor_collector, FALSE);
+               } else if (!strcmp (minor_collector_opt, "simple-par")) {
+                       sgen_simple_nursery_init (&sgen_minor_collector, TRUE);
                } else if (!strcmp (minor_collector_opt, "split")) {
                        sgen_split_nursery_init (&sgen_minor_collector);
                } else {
@@ -3187,6 +3265,7 @@ sgen_gc_init (void)
 
        if ((env = g_getenv (MONO_GC_DEBUG_NAME)) || gc_debug_options) {
                debug_opts = g_strdup_printf ("%s,%s", gc_debug_options ? gc_debug_options  : "", env ? env : "");
+               g_free (env);
        }
 
        if (debug_opts) {
@@ -3342,9 +3421,9 @@ sgen_gc_init (void)
        if (major_collector.post_param_init)
                major_collector.post_param_init (&major_collector);
 
-       if (major_collector.needs_thread_pool) {
+       if (major_collector.is_concurrent || sgen_minor_collector.is_parallel) {
                int num_workers = 1;
-               if (major_collector.is_parallel) {
+               if (major_collector.is_parallel || sgen_minor_collector.is_parallel) {
                        /* FIXME Detect the number of physical cores, instead of logical */
                        num_workers = mono_cpu_count () / 2;
                        if (num_workers < 1)
@@ -3408,6 +3487,12 @@ sgen_get_major_collector (void)
        return &major_collector;
 }
 
+SgenMinorCollector*
+sgen_get_minor_collector (void)
+{
+       return &sgen_minor_collector;
+}
+
 SgenRememberedSet*
 sgen_get_remset (void)
 {
index e8df83337a63fc88e57f4a40aa34a0ea8c68f39b..8cf5a46fa500f40683e1d916f7a8ac08807c2349 100644 (file)
@@ -35,6 +35,7 @@ typedef struct _SgenThreadInfo SgenThreadInfo;
 #include "mono/sgen/sgen-hash-table.h"
 #include "mono/sgen/sgen-protocol.h"
 #include "mono/sgen/gc-internal-agnostic.h"
+#include "mono/sgen/sgen-thread-pool.h"
 
 /* The method used to clear the nursery */
 /* Clearing at nursery collections is the safest, but has bad interactions with caches.
@@ -117,7 +118,7 @@ extern guint64 stat_objects_copied_major;
                g_error (__VA_ARGS__);  \
 } } while (0)
 
-#ifndef HOST_WIN32
+#ifdef HAVE_LOCALTIME_R
 # define LOG_TIMESTAMP  \
        do {    \
                time_t t;                                                                       \
@@ -559,11 +560,13 @@ sgen_nursery_is_object_alive (GCObject *obj)
 
 typedef struct {
        gboolean is_split;
+       gboolean is_parallel;
 
        GCObject* (*alloc_for_promotion) (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references);
 
        SgenObjectOperations serial_ops;
        SgenObjectOperations serial_ops_with_concurrent_major;
+       SgenObjectOperations parallel_ops;
 
        void (*prepare_to_space) (char *to_space_bitmap, size_t space_bitmap_size);
        void (*clear_fragments) (void);
@@ -578,7 +581,7 @@ typedef struct {
 
 extern SgenMinorCollector sgen_minor_collector;
 
-void sgen_simple_nursery_init (SgenMinorCollector *collector);
+void sgen_simple_nursery_init (SgenMinorCollector *collector, gboolean parallel);
 void sgen_split_nursery_init (SgenMinorCollector *collector);
 
 /* Updating references */
@@ -591,7 +594,7 @@ sgen_update_reference (GCObject **p, GCObject *o, gboolean allow_null)
 {
        if (!allow_null)
                SGEN_ASSERT (0, o, "Cannot update a reference with a NULL pointer");
-       SGEN_ASSERT (0, !sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()), "Can't update a reference in the worker thread");
+       SGEN_ASSERT (0, !sgen_workers_is_worker_thread (mono_native_thread_id_get ()), "Can't update a reference in the worker thread");
        *p = o;
 }
 
@@ -634,7 +637,6 @@ struct _SgenMajorCollector {
        size_t section_size;
        gboolean is_concurrent;
        gboolean is_parallel;
-       gboolean needs_thread_pool;
        gboolean supports_cardtable;
        gboolean sweeps_lazily;
 
@@ -691,6 +693,7 @@ struct _SgenMajorCollector {
        guint8* (*get_cardtable_mod_union_for_reference) (char *object);
        long long (*get_and_reset_num_major_objects_marked) (void);
        void (*count_cards) (long long *num_total_cards, long long *num_marked_cards);
+       SgenThreadPool* (*get_sweep_pool) (void);
 
        void (*worker_init_cb) (gpointer worker);
 };
@@ -701,6 +704,7 @@ void sgen_marksweep_init (SgenMajorCollector *collector);
 void sgen_marksweep_conc_init (SgenMajorCollector *collector);
 void sgen_marksweep_conc_par_init (SgenMajorCollector *collector);
 SgenMajorCollector* sgen_get_major_collector (void);
+SgenMinorCollector* sgen_get_minor_collector (void);
 
 
 typedef struct _SgenRememberedSet {
@@ -711,11 +715,10 @@ typedef struct _SgenRememberedSet {
        void (*wbarrier_generic_nostore) (gpointer ptr);
        void (*record_pointer) (gpointer ptr);
 
-       void (*scan_remsets) (ScanCopyContext ctx);
+       void (*start_scan_remsets) (void);
 
        void (*clear_cards) (void);
 
-       void (*finish_minor_collection) (void);
        gboolean (*find_address) (char *addr);
        gboolean (*find_address_with_cards) (char *cards_start, guint8 *cards, char *addr);
 } SgenRememberedSet;
index bbaefe07575539c21e9ba7f02708f8d5a8b1148a..3ea4037af245c7489790da11c2836eae471d4bd0 100644 (file)
@@ -47,7 +47,7 @@
 #define SGEN_GRAY_QUEUE_HEADER_SIZE    3
 #endif
 
-#define SGEN_GRAY_QUEUE_SECTION_SIZE   (128 - SGEN_GRAY_QUEUE_HEADER_SIZE)
+#define SGEN_GRAY_QUEUE_SECTION_SIZE   (512 - SGEN_GRAY_QUEUE_HEADER_SIZE)
 
 #ifdef SGEN_CHECK_GRAY_OBJECT_SECTIONS
 typedef enum {
index 67b422c1990c10c52989478c2331e14b0f1dfbb3..04ab32dab84a0dbc96e64bf00e7293ed6eee2e8d 100644 (file)
@@ -187,6 +187,9 @@ static volatile int sweep_state = SWEEP_STATE_SWEPT;
 static gboolean concurrent_mark;
 static gboolean concurrent_sweep = TRUE;
 
+SgenThreadPool sweep_pool_inst;
+SgenThreadPool *sweep_pool;
+
 #define BLOCK_IS_TAGGED_HAS_REFERENCES(bl)     SGEN_POINTER_IS_TAGGED_1 ((bl))
 #define BLOCK_TAG_HAS_REFERENCES(bl)           SGEN_POINTER_TAG_1 ((bl))
 
@@ -727,7 +730,6 @@ get_block:
                         */
                        if (SGEN_CAS_PTR ((volatile gpointer *)&free_blocks [size_index], next_free, block) != block)
                                goto get_block;
-                       g_assert (block->free_list);
                        block->next_free = free_blocks_local [size_index];
                        free_blocks_local [size_index] = block;
 
@@ -919,7 +921,7 @@ major_finish_sweep_checking (void)
  wait:
        job = sweep_job;
        if (job)
-               sgen_thread_pool_job_wait (job);
+               sgen_thread_pool_job_wait (sweep_pool, job);
        SGEN_ASSERT (0, !sweep_job, "Why did the sweep job not null itself?");
        SGEN_ASSERT (0, sweep_state == SWEEP_STATE_SWEPT, "How is the sweep job done but we're not swept?");
 }
@@ -1556,6 +1558,25 @@ sgen_worker_clear_free_block_lists (WorkerData *worker)
        }
 }
 
+static void
+sgen_worker_clear_free_block_lists_evac (WorkerData *worker)
+{
+       int i, j;
+
+       if (!worker->free_block_lists)
+               return;
+
+       for (i = 0; i < MS_BLOCK_TYPE_MAX; i++) {
+               for (j = 0; j < num_block_obj_sizes; j++) {
+                       if (((MSBlockInfo***) worker->free_block_lists) [i][j])
+                               SGEN_ASSERT (0, !((MSBlockInfo***) worker->free_block_lists) [i][j]->next_free, "Why do we have linked free blocks on the workers");
+
+                       if (evacuate_block_obj_sizes [j])
+                               ((MSBlockInfo***) worker->free_block_lists) [i][j] = NULL;
+               }
+       }
+}
+
 static void
 sweep_start (void)
 {
@@ -1788,7 +1809,7 @@ sweep_job_func (void *thread_data_untyped, SgenThreadPoolJob *job)
         */
        if (concurrent_sweep && lazy_sweep) {
                sweep_blocks_job = sgen_thread_pool_job_alloc ("sweep_blocks", sweep_blocks_job_func, sizeof (SgenThreadPoolJob));
-               sgen_thread_pool_job_enqueue (sweep_blocks_job);
+               sgen_thread_pool_job_enqueue (sweep_pool, sweep_blocks_job);
        }
 
        sweep_finish ();
@@ -1837,7 +1858,7 @@ major_sweep (void)
        SGEN_ASSERT (0, !sweep_job, "We haven't finished the last sweep?");
        if (concurrent_sweep) {
                sweep_job = sgen_thread_pool_job_alloc ("sweep", sweep_job_func, sizeof (SgenThreadPoolJob));
-               sgen_thread_pool_job_enqueue (sweep_job);
+               sgen_thread_pool_job_enqueue (sweep_pool, sweep_job);
        } else {
                sweep_job_func (NULL, NULL);
        }
@@ -2039,6 +2060,9 @@ major_start_major_collection (void)
                sgen_evacuation_freelist_blocks (&free_block_lists [MS_BLOCK_FLAG_REFS][i], i);
        }
 
+       /* We expect workers to have very few blocks on the freelist, just evacuate them */
+       sgen_workers_foreach (sgen_worker_clear_free_block_lists_evac);
+
        if (lazy_sweep && concurrent_sweep) {
                /*
                 * sweep_blocks_job is created before sweep_finish, which we wait for above
@@ -2047,7 +2071,7 @@ major_start_major_collection (void)
                 */
                SgenThreadPoolJob *job = sweep_blocks_job;
                if (job)
-                       sgen_thread_pool_job_wait (job);
+                       sgen_thread_pool_job_wait (sweep_pool, job);
        }
 
        if (lazy_sweep && !concurrent_sweep)
@@ -2087,6 +2111,12 @@ major_finish_major_collection (ScannedObjectCounts *counts)
 #endif
 }
 
+static SgenThreadPool*
+major_get_sweep_pool (void)
+{
+       return sweep_pool;
+}
+
 static int
 compare_pointers (const void *va, const void *vb) {
        char *a = *(char**)va, *b = *(char**)vb;
@@ -2693,7 +2723,6 @@ static void
 post_param_init (SgenMajorCollector *collector)
 {
        collector->sweeps_lazily = lazy_sweep;
-       collector->needs_thread_pool = concurrent_mark || concurrent_sweep;
 }
 
 /* We are guaranteed to be called by the worker in question */
@@ -2712,6 +2741,12 @@ sgen_worker_init_callback (gpointer worker_untyped)
        mono_native_tls_set_value (worker_block_free_list_key, worker_free_blocks);
 }
 
+static void
+thread_pool_init_func (void *data_untyped)
+{
+       sgen_client_thread_register_worker ();
+}
+
 static void
 sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurrent, gboolean is_parallel)
 {
@@ -2748,6 +2783,12 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
        for (i = 0; i < MS_NUM_FAST_BLOCK_OBJ_SIZE_INDEXES * 8; ++i)
                g_assert (MS_BLOCK_OBJ_SIZE_INDEX (i) == ms_find_block_obj_size_index (i));
 
+       /* We can do this because we always init the minor before the major */
+       if (is_parallel || sgen_get_minor_collector ()->is_parallel) {
+               mono_native_tls_alloc (&worker_block_free_list_key, NULL);
+               collector->worker_init_cb = sgen_worker_init_callback;
+       }
+
        mono_counters_register ("# major blocks allocated", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_major_blocks_alloced);
        mono_counters_register ("# major blocks freed", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_major_blocks_freed);
        mono_counters_register ("# major blocks lazy swept", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_major_blocks_lazy_swept);
@@ -2761,7 +2802,6 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
        concurrent_mark = is_concurrent;
        collector->is_concurrent = is_concurrent;
        collector->is_parallel = is_parallel;
-       collector->needs_thread_pool = is_concurrent || concurrent_sweep;
        collector->get_and_reset_num_major_objects_marked = major_get_and_reset_num_major_objects_marked;
        collector->supports_cardtable = TRUE;
 
@@ -2807,6 +2847,7 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
        collector->is_valid_object = major_is_valid_object;
        collector->describe_pointer = major_describe_pointer;
        collector->count_cards = major_count_cards;
+       collector->get_sweep_pool = major_get_sweep_pool;
 
        collector->major_ops_serial.copy_or_mark_object = major_copy_or_mark_object_canonical;
        collector->major_ops_serial.scan_object = major_scan_object_with_evacuation;
@@ -2837,10 +2878,6 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
                        collector->major_ops_conc_par_finish.scan_vtype = major_scan_vtype_par_with_evacuation;
                        collector->major_ops_conc_par_finish.scan_ptr_field = major_scan_ptr_field_par_with_evacuation;
                        collector->major_ops_conc_par_finish.drain_gray_stack = drain_gray_stack_par;
-
-                       collector->worker_init_cb = sgen_worker_init_callback;
-
-                       mono_native_tls_alloc (&worker_block_free_list_key, NULL);
                }
        }
 
@@ -2870,6 +2907,12 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
 
        /*cardtable requires major pages to be 8 cards aligned*/
        g_assert ((MS_BLOCK_SIZE % (8 * CARD_SIZE_IN_BYTES)) == 0);
+
+       if (concurrent_sweep) {
+               SgenThreadPool **thread_datas = &sweep_pool;
+               sweep_pool = &sweep_pool_inst;
+               sgen_thread_pool_init (sweep_pool, 1, thread_pool_init_func, NULL, NULL, NULL, (SgenThreadPoolData**)&thread_datas);
+       }
 }
 
 void
index 8dae5a062fd6ddcc54ee582cd161624449ee6a11..3bf90115b854910c743596a6e32c1a061e35d734 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "mono/sgen/sgen-gc.h"
 #include "mono/sgen/sgen-memory-governor.h"
-#include "mono/sgen/sgen-thread-pool.h"
+#include "mono/sgen/sgen-workers.h"
 #include "mono/sgen/sgen-client.h"
 
 #define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(DEFAULT_NURSERY_SIZE * default_allowance_nursery_size_ratio))
@@ -459,7 +459,7 @@ gboolean
 sgen_memgov_try_alloc_space (mword size, int space)
 {
        if (sgen_memgov_available_free_space () < size) {
-               SGEN_ASSERT (4, !sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()), "Memory shouldn't run out in worker thread");
+               SGEN_ASSERT (4, !sgen_workers_is_worker_thread (mono_native_thread_id_get ()), "Memory shouldn't run out in worker thread");
                return FALSE;
        }
 
index 9ba0d129522e677b98bf87768d72b09c1e2fc2c4..3ad10aac4447fb2608803abd67bd71b77cf8441d 100644 (file)
 
 #if defined(SGEN_SIMPLE_NURSERY)
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+/* Not supported with concurrent major yet */
+#define SERIAL_COPY_OBJECT simple_par_nursery_copy_object
+#define SERIAL_COPY_OBJECT_FROM_OBJ simple_par_nursery_copy_object_from_obj
+#else
 #ifdef SGEN_CONCURRENT_MAJOR
 #define SERIAL_COPY_OBJECT simple_nursery_serial_with_concurrent_major_copy_object
 #define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_with_concurrent_major_copy_object_from_obj
@@ -21,6 +26,7 @@
 #define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object
 #define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj
 #endif
+#endif
 
 #elif defined (SGEN_SPLIT_NURSERY)
 
@@ -108,7 +114,11 @@ SERIAL_COPY_OBJECT (GCObject **obj_slot, SgenGrayQueue *queue)
 
        HEAVY_STAT (++stat_objects_copied_nursery);
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+       copy = copy_object_no_checks_par (obj, queue);
+#else
        copy = copy_object_no_checks (obj, queue);
+#endif
        SGEN_UPDATE_REFERENCE (obj_slot, copy);
 }
 
@@ -214,7 +224,11 @@ SERIAL_COPY_OBJECT_FROM_OBJ (GCObject **obj_slot, SgenGrayQueue *queue)
 
        HEAVY_STAT (++stat_objects_copied_nursery);
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+       copy = copy_object_no_checks_par (obj, queue);
+#else
        copy = copy_object_no_checks (obj, queue);
+#endif
 #ifdef SGEN_CONCURRENT_MAJOR
        /*
         * If an object is evacuated to the major heap and a reference to it, from the major
index aadfe068e24f401bf99510dcebda4595031c6b91..b92d309f4ec1228d02086deb5d856902459c94cc 100644 (file)
@@ -18,6 +18,12 @@ extern guint64 stat_scan_object_called_nursery;
 
 #if defined(SGEN_SIMPLE_NURSERY)
 
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+#define SERIAL_SCAN_OBJECT simple_par_nursery_serial_scan_object
+#define SERIAL_SCAN_VTYPE simple_par_nursery_serial_scan_vtype
+#define SERIAL_SCAN_PTR_FIELD simple_par_nursery_serial_scan_ptr_field
+#define SERIAL_DRAIN_GRAY_STACK simple_par_nursery_serial_drain_gray_stack
+#else
 #ifdef SGEN_CONCURRENT_MAJOR
 #define SERIAL_SCAN_OBJECT simple_nursery_serial_with_concurrent_major_scan_object
 #define SERIAL_SCAN_VTYPE simple_nursery_serial_with_concurrent_major_scan_vtype
@@ -29,6 +35,7 @@ extern guint64 stat_scan_object_called_nursery;
 #define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_scan_ptr_field
 #define SERIAL_DRAIN_GRAY_STACK simple_nursery_serial_drain_gray_stack
 #endif
+#endif
 
 #elif defined (SGEN_SPLIT_NURSERY)
 
@@ -104,16 +111,31 @@ SERIAL_SCAN_PTR_FIELD (GCObject *full_object, GCObject **ptr, SgenGrayQueue *que
 static gboolean
 SERIAL_DRAIN_GRAY_STACK (SgenGrayQueue *queue)
 {
-        for (;;) {
-                GCObject *obj;
-                SgenDescriptor desc;
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+       int i;
+       /*
+        * We do bounded iteration so we can switch to optimized context
+        * when we are the last worker remaining.
+        */
+       for (i = 0; i < 32; i++) {
+#else
+       for (;;) {
+#endif
+               GCObject *obj;
+               SgenDescriptor desc;
+
+#ifdef SGEN_SIMPLE_PAR_NURSERY
+               GRAY_OBJECT_DEQUEUE_PARALLEL (queue, &obj, &desc);
+#else
+               GRAY_OBJECT_DEQUEUE_SERIAL (queue, &obj, &desc);
+#endif
+               if (!obj)
+                       return TRUE;
 
-                GRAY_OBJECT_DEQUEUE_SERIAL (queue, &obj, &desc);
-                if (!obj)
-                        return TRUE;
+               SERIAL_SCAN_OBJECT (obj, desc, queue);
+       }
 
-                SERIAL_SCAN_OBJECT (obj, desc, queue);
-        }
+       return FALSE;
 }
 
 #define FILL_MINOR_COLLECTOR_SCAN_OBJECT(ops)  do {                    \
index 419e90a482a50faa961382308edd80844b743a17..f86b05e51c963dd4de1f6c5dba3728732db8b97a 100644 (file)
@@ -16,7 +16,7 @@
 #include "sgen-gc.h"
 #include "sgen-protocol.h"
 #include "sgen-memory-governor.h"
-#include "sgen-thread-pool.h"
+#include "sgen-workers.h"
 #include "sgen-client.h"
 #include "mono/utils/mono-membar.h"
 #include "mono/utils/mono-proclib.h"
@@ -365,11 +365,17 @@ protocol_entry (unsigned char type, gpointer data, int size)
        buffer->buffer [index++] = type;
        /* We should never change the header format */
        if (include_worker_index) {
+               int worker_index;
+               MonoNativeThreadId tid = mono_native_thread_id_get ();
                /*
                 * If the thread is not a worker thread we insert 0, which is interpreted
                 * as gc thread. Worker indexes are 1 based.
                 */
-               buffer->buffer [index++] = (unsigned char) sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ());
+               worker_index = sgen_workers_is_worker_thread (tid);
+               if (!worker_index)
+                       worker_index = sgen_thread_pool_is_thread_pool_thread (major_collector.get_sweep_pool (), tid);
+               /* FIXME Consider using different index bases for different thread pools */
+               buffer->buffer [index++] = (unsigned char) worker_index;
        }
        memcpy (buffer->buffer + index, data, size);
        index += size;
index 24a59f759a97602d2d1c0d99558201d775940bf9..4234559e9e8cec8ced5617f60fe64e9e9e862c38 100644 (file)
@@ -66,6 +66,7 @@ init_nursery (SgenFragmentAllocator *allocator, char *start, char *end)
 #define collector_pin_object(obj, queue) sgen_pin_object (obj, queue);
 #define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion
 
+#define COPY_OR_MARK_PARALLEL
 #include "sgen-copy-object.h"
 
 #define SGEN_SIMPLE_NURSERY
@@ -80,6 +81,19 @@ fill_serial_ops (SgenObjectOperations *ops)
        FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
 }
 
+#define SGEN_SIMPLE_PAR_NURSERY
+
+#include "sgen-minor-copy-object.h"
+#include "sgen-minor-scan-object.h"
+
+static void
+fill_parallel_ops (SgenObjectOperations *ops)
+{
+       ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
+       FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
+}
+
+#undef SGEN_SIMPLE_PAR_NURSERY
 #define SGEN_CONCURRENT_MAJOR
 
 #include "sgen-minor-copy-object.h"
@@ -93,9 +107,10 @@ fill_serial_with_concurrent_major_ops (SgenObjectOperations *ops)
 }
 
 void
-sgen_simple_nursery_init (SgenMinorCollector *collector)
+sgen_simple_nursery_init (SgenMinorCollector *collector, gboolean parallel)
 {
        collector->is_split = FALSE;
+       collector->is_parallel = parallel;
 
        collector->alloc_for_promotion = alloc_for_promotion;
 
@@ -108,6 +123,7 @@ sgen_simple_nursery_init (SgenMinorCollector *collector)
 
        fill_serial_ops (&collector->serial_ops);
        fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major);
+       fill_parallel_ops (&collector->parallel_ops);
 }
 
 
index 078e1908d4e36855e3dfe2fd0202371793210911..38dc0c8c3a7a68b5b836e361ee0931471fcad54b 100644 (file)
@@ -452,6 +452,7 @@ void
 sgen_split_nursery_init (SgenMinorCollector *collector)
 {
        collector->is_split = TRUE;
+       collector->is_parallel = FALSE;
 
        collector->alloc_for_promotion = minor_alloc_for_promotion;
 
index 6f164d278c1b7d9b9a075c3de72506c0d2ba021a..a7abfad24472822f85e7f51632aa998cb913f05c 100644 (file)
 
 #include "mono/sgen/sgen-gc.h"
 #include "mono/sgen/sgen-thread-pool.h"
-#include "mono/sgen/sgen-pointer-queue.h"
 #include "mono/utils/mono-os-mutex.h"
-#ifndef SGEN_WITHOUT_MONO
-#include "mono/utils/mono-threads.h"
-#endif
-
-#define MAX_NUM_THREADS 8
-
-static mono_mutex_t lock;
-static mono_cond_t work_cond;
-static mono_cond_t done_cond;
-
-static int threads_num = 0;
-static MonoNativeThreadId threads [MAX_NUM_THREADS];
-
-/* Only accessed with the lock held. */
-static SgenPointerQueue job_queue;
-
-static SgenThreadPoolThreadInitFunc thread_init_func;
-static SgenThreadPoolIdleJobFunc idle_job_func;
-static SgenThreadPoolContinueIdleJobFunc continue_idle_job_func;
-static SgenThreadPoolShouldWorkFunc should_work_func;
-
-static volatile gboolean threadpool_shutdown;
-static volatile int threads_finished = 0;
 
 enum {
        STATE_WAITING,
@@ -46,10 +22,10 @@ enum {
 
 /* Assumes that the lock is held. */
 static SgenThreadPoolJob*
-get_job_and_set_in_progress (void)
+get_job_and_set_in_progress (SgenThreadPool *pool)
 {
-       for (size_t i = 0; i < job_queue.next_slot; ++i) {
-               SgenThreadPoolJob *job = (SgenThreadPoolJob *)job_queue.data [i];
+       for (size_t i = 0; i < pool->job_queue.next_slot; ++i) {
+               SgenThreadPoolJob *job = (SgenThreadPoolJob *)pool->job_queue.data [i];
                if (job->state == STATE_WAITING) {
                        job->state = STATE_IN_PROGRESS;
                        return job;
@@ -60,10 +36,10 @@ get_job_and_set_in_progress (void)
 
 /* Assumes that the lock is held. */
 static ssize_t
-find_job_in_queue (SgenThreadPoolJob *job)
+find_job_in_queue (SgenThreadPool *pool, SgenThreadPoolJob *job)
 {
-       for (ssize_t i = 0; i < job_queue.next_slot; ++i) {
-               if (job_queue.data [i] == job)
+       for (ssize_t i = 0; i < pool->job_queue.next_slot; ++i) {
+               if (pool->job_queue.data [i] == job)
                        return i;
        }
        return -1;
@@ -71,45 +47,47 @@ find_job_in_queue (SgenThreadPoolJob *job)
 
 /* Assumes that the lock is held. */
 static void
-remove_job (SgenThreadPoolJob *job)
+remove_job (SgenThreadPool *pool, SgenThreadPoolJob *job)
 {
        ssize_t index;
        SGEN_ASSERT (0, job->state == STATE_DONE, "Why are we removing a job that's not done?");
-       index = find_job_in_queue (job);
+       index = find_job_in_queue (pool, job);
        SGEN_ASSERT (0, index >= 0, "Why is the job we're trying to remove not in the queue?");
-       job_queue.data [index] = NULL;
-       sgen_pointer_queue_remove_nulls (&job_queue);
+       pool->job_queue.data [index] = NULL;
+       sgen_pointer_queue_remove_nulls (&pool->job_queue);
        sgen_thread_pool_job_free (job);
 }
 
 static gboolean
-continue_idle_job (void *thread_data)
+continue_idle_job (SgenThreadPool *pool, void *thread_data)
 {
-       if (!continue_idle_job_func)
+       if (!pool->continue_idle_job_func)
                return FALSE;
-       return continue_idle_job_func (thread_data);
+       return pool->continue_idle_job_func (thread_data);
 }
 
 static gboolean
-should_work (void *thread_data)
+should_work (SgenThreadPool *pool, void *thread_data)
 {
-       if (!should_work_func)
+       if (!pool->should_work_func)
                return TRUE;
-       return should_work_func (thread_data);
+       return pool->should_work_func (thread_data);
 }
 
 static mono_native_thread_return_t
-thread_func (void *thread_data)
+thread_func (SgenThreadPoolData *thread_data)
 {
-       thread_init_func (thread_data);
+       SgenThreadPool *pool = thread_data->pool;
+
+       pool->thread_init_func (thread_data);
 
-       mono_os_mutex_lock (&lock);
+       mono_os_mutex_lock (&pool->lock);
        for (;;) {
                gboolean do_idle;
                SgenThreadPoolJob *job;
 
-               if (!should_work (thread_data)) {
-                       mono_os_cond_wait (&work_cond, &lock);
+               if (!should_work (pool, thread_data) && !pool->threadpool_shutdown) {
+                       mono_os_cond_wait (&pool->work_cond, &pool->lock);
                        continue;
                }
                /*
@@ -118,51 +96,51 @@ thread_func (void *thread_data)
                 * main thread might then set continue idle and signal us before we can take
                 * the lock, and we'd lose the signal.
                 */
-               do_idle = continue_idle_job (thread_data);
-               job = get_job_and_set_in_progress ();
+               do_idle = continue_idle_job (pool, thread_data);
+               job = get_job_and_set_in_progress (pool);
 
-               if (!job && !do_idle && !threadpool_shutdown) {
+               if (!job && !do_idle && !pool->threadpool_shutdown) {
                        /*
                         * pthread_cond_wait() can return successfully despite the condition
                         * not being signalled, so we have to run this in a loop until we
                         * really have work to do.
                         */
-                       mono_os_cond_wait (&work_cond, &lock);
+                       mono_os_cond_wait (&pool->work_cond, &pool->lock);
                        continue;
                }
 
-               mono_os_mutex_unlock (&lock);
+               mono_os_mutex_unlock (&pool->lock);
 
                if (job) {
                        job->func (thread_data, job);
 
-                       mono_os_mutex_lock (&lock);
+                       mono_os_mutex_lock (&pool->lock);
 
                        SGEN_ASSERT (0, job->state == STATE_IN_PROGRESS, "The job should still be in progress.");
                        job->state = STATE_DONE;
-                       remove_job (job);
+                       remove_job (pool, job);
                        /*
                         * Only the main GC thread will ever wait on the done condition, so we don't
                         * have to broadcast.
                         */
-                       mono_os_cond_signal (&done_cond);
+                       mono_os_cond_signal (&pool->done_cond);
                } else if (do_idle) {
-                       SGEN_ASSERT (0, idle_job_func, "Why do we have idle work when there's no idle job function?");
+                       SGEN_ASSERT (0, pool->idle_job_func, "Why do we have idle work when there's no idle job function?");
                        do {
-                               idle_job_func (thread_data);
-                               do_idle = continue_idle_job (thread_data);
-                       } while (do_idle && !job_queue.next_slot);
+                               pool->idle_job_func (thread_data);
+                               do_idle = continue_idle_job (pool, thread_data);
+                       } while (do_idle && !pool->job_queue.next_slot);
 
-                       mono_os_mutex_lock (&lock);
+                       mono_os_mutex_lock (&pool->lock);
 
                        if (!do_idle)
-                               mono_os_cond_signal (&done_cond);
+                               mono_os_cond_signal (&pool->done_cond);
                } else {
-                       SGEN_ASSERT (0, threadpool_shutdown, "Why did we unlock if no jobs and not shutting down?");
-                       mono_os_mutex_lock (&lock);
-                       threads_finished++;
-                       mono_os_cond_signal (&done_cond);
-                       mono_os_mutex_unlock (&lock);
+                       SGEN_ASSERT (0, pool->threadpool_shutdown, "Why did we unlock if no jobs and not shutting down?");
+                       mono_os_mutex_lock (&pool->lock);
+                       pool->threads_finished++;
+                       mono_os_cond_signal (&pool->done_cond);
+                       mono_os_mutex_unlock (&pool->lock);
                        return 0;
                }
        }
@@ -171,41 +149,49 @@ thread_func (void *thread_data)
 }
 
 void
-sgen_thread_pool_init (int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, SgenThreadPoolShouldWorkFunc should_work_func_p, void **thread_datas)
+sgen_thread_pool_init (SgenThreadPool *pool, int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, SgenThreadPoolShouldWorkFunc should_work_func_p, SgenThreadPoolData **thread_datas)
 {
        int i;
 
-       threads_num = (num_threads < MAX_NUM_THREADS) ? num_threads : MAX_NUM_THREADS;
+       SGEN_ASSERT (0, num_threads > 0, "Why are we creating a threadpool with no threads?");
+
+       pool->threads_num = (num_threads < MAX_NUM_THREADS) ? num_threads : MAX_NUM_THREADS;
 
-       mono_os_mutex_init (&lock);
-       mono_os_cond_init (&work_cond);
-       mono_os_cond_init (&done_cond);
+       mono_os_mutex_init (&pool->lock);
+       mono_os_cond_init (&pool->work_cond);
+       mono_os_cond_init (&pool->done_cond);
 
-       thread_init_func = init_func;
-       idle_job_func = idle_func;
-       continue_idle_job_func = continue_idle_func;
-       should_work_func = should_work_func_p;
+       pool->thread_init_func = init_func;
+       pool->idle_job_func = idle_func;
+       pool->continue_idle_job_func = continue_idle_func;
+       pool->should_work_func = should_work_func_p;
 
-       for (i = 0; i < threads_num; i++)
-               mono_native_thread_create (&threads [i], thread_func, thread_datas ? thread_datas [i] : NULL);
+       sgen_pointer_queue_init (&pool->job_queue, 0);
+       pool->threads_finished = 0;
+       pool->threadpool_shutdown = FALSE;
+
+       for (i = 0; i < pool->threads_num; i++) {
+               thread_datas [i]->pool = pool;
+               mono_native_thread_create (&pool->threads [i], thread_func, thread_datas [i]);
+       }
 }
 
 void
-sgen_thread_pool_shutdown (void)
+sgen_thread_pool_shutdown (SgenThreadPool *pool)
 {
-       if (!threads_num)
+       if (!pool)
                return;
 
-       mono_os_mutex_lock (&lock);
-       threadpool_shutdown = TRUE;
-       mono_os_cond_broadcast (&work_cond);
-       while (threads_finished < threads_num)
-               mono_os_cond_wait (&done_cond, &lock);
-       mono_os_mutex_unlock (&lock);
+       mono_os_mutex_lock (&pool->lock);
+       pool->threadpool_shutdown = TRUE;
+       mono_os_cond_broadcast (&pool->work_cond);
+       while (pool->threads_finished < pool->threads_num)
+               mono_os_cond_wait (&pool->done_cond, &pool->lock);
+       mono_os_mutex_unlock (&pool->lock);
 
-       mono_os_mutex_destroy (&lock);
-       mono_os_cond_destroy (&work_cond);
-       mono_os_cond_destroy (&done_cond);
+       mono_os_mutex_destroy (&pool->lock);
+       mono_os_cond_destroy (&pool->work_cond);
+       mono_os_cond_destroy (&pool->done_cond);
 }
 
 SgenThreadPoolJob*
@@ -226,74 +212,77 @@ sgen_thread_pool_job_free (SgenThreadPoolJob *job)
 }
 
 void
-sgen_thread_pool_job_enqueue (SgenThreadPoolJob *job)
+sgen_thread_pool_job_enqueue (SgenThreadPool *pool, SgenThreadPoolJob *job)
 {
-       mono_os_mutex_lock (&lock);
+       mono_os_mutex_lock (&pool->lock);
 
-       sgen_pointer_queue_add (&job_queue, job);
-       mono_os_cond_signal (&work_cond);
+       sgen_pointer_queue_add (&pool->job_queue, job);
+       mono_os_cond_signal (&pool->work_cond);
 
-       mono_os_mutex_unlock (&lock);
+       mono_os_mutex_unlock (&pool->lock);
 }
 
 void
-sgen_thread_pool_job_wait (SgenThreadPoolJob *job)
+sgen_thread_pool_job_wait (SgenThreadPool *pool, SgenThreadPoolJob *job)
 {
        SGEN_ASSERT (0, job, "Where's the job?");
 
-       mono_os_mutex_lock (&lock);
+       mono_os_mutex_lock (&pool->lock);
 
-       while (find_job_in_queue (job) >= 0)
-               mono_os_cond_wait (&done_cond, &lock);
+       while (find_job_in_queue (pool, job) >= 0)
+               mono_os_cond_wait (&pool->done_cond, &pool->lock);
 
-       mono_os_mutex_unlock (&lock);
+       mono_os_mutex_unlock (&pool->lock);
 }
 
 void
-sgen_thread_pool_idle_signal (void)
+sgen_thread_pool_idle_signal (SgenThreadPool *pool)
 {
-       SGEN_ASSERT (0, idle_job_func, "Why are we signaling idle without an idle function?");
+       SGEN_ASSERT (0, pool->idle_job_func, "Why are we signaling idle without an idle function?");
 
-       mono_os_mutex_lock (&lock);
+       mono_os_mutex_lock (&pool->lock);
 
-       if (continue_idle_job_func (NULL))
-               mono_os_cond_broadcast (&work_cond);
+       if (pool->continue_idle_job_func (NULL))
+               mono_os_cond_broadcast (&pool->work_cond);
 
-       mono_os_mutex_unlock (&lock);
+       mono_os_mutex_unlock (&pool->lock);
 }
 
 void
-sgen_thread_pool_idle_wait (void)
+sgen_thread_pool_idle_wait (SgenThreadPool *pool)
 {
-       SGEN_ASSERT (0, idle_job_func, "Why are we waiting for idle without an idle function?");
+       SGEN_ASSERT (0, pool->idle_job_func, "Why are we waiting for idle without an idle function?");
 
-       mono_os_mutex_lock (&lock);
+       mono_os_mutex_lock (&pool->lock);
 
-       while (continue_idle_job_func (NULL))
-               mono_os_cond_wait (&done_cond, &lock);
+       while (pool->continue_idle_job_func (NULL))
+               mono_os_cond_wait (&pool->done_cond, &pool->lock);
 
-       mono_os_mutex_unlock (&lock);
+       mono_os_mutex_unlock (&pool->lock);
 }
 
 void
-sgen_thread_pool_wait_for_all_jobs (void)
+sgen_thread_pool_wait_for_all_jobs (SgenThreadPool *pool)
 {
-       mono_os_mutex_lock (&lock);
+       mono_os_mutex_lock (&pool->lock);
 
-       while (!sgen_pointer_queue_is_empty (&job_queue))
-               mono_os_cond_wait (&done_cond, &lock);
+       while (!sgen_pointer_queue_is_empty (&pool->job_queue))
+               mono_os_cond_wait (&pool->done_cond, &pool->lock);
 
-       mono_os_mutex_unlock (&lock);
+       mono_os_mutex_unlock (&pool->lock);
 }
 
 /* Return 0 if is not a thread pool thread or the thread number otherwise */
 int
-sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread)
+sgen_thread_pool_is_thread_pool_thread (SgenThreadPool *pool, MonoNativeThreadId some_thread)
 {
        int i;
 
-       for (i = 0; i < threads_num; i++) {
-               if (some_thread == threads [i])
+       if (!pool)
+               return 0;
+
+       for (i = 0; i < pool->threads_num; i++) {
+               if (some_thread == pool->threads [i])
                        return i + 1;
        }
 
index ce4bb11e321ee58668336c2a6989fa7ee71d4e6e..1b48e4433f040137bf37e0368f6b126b17a63c4e 100644 (file)
 #ifndef __MONO_SGEN_THREAD_POOL_H__
 #define __MONO_SGEN_THREAD_POOL_H__
 
+#include "mono/sgen/sgen-pointer-queue.h"
+#include "mono/utils/mono-threads.h"
+
 typedef struct _SgenThreadPoolJob SgenThreadPoolJob;
+typedef struct _SgenThreadPool SgenThreadPool;
+typedef struct _SgenThreadPoolData SgenThreadPoolData;
 
 typedef void (*SgenThreadPoolJobFunc) (void *thread_data, SgenThreadPoolJob *job);
+typedef void (*SgenThreadPoolThreadInitFunc) (void*);
+typedef void (*SgenThreadPoolIdleJobFunc) (void*);
+typedef gboolean (*SgenThreadPoolContinueIdleJobFunc) (void*);
+typedef gboolean (*SgenThreadPoolShouldWorkFunc) (void*);
 
 struct _SgenThreadPoolJob {
        const char *name;
@@ -21,28 +30,49 @@ struct _SgenThreadPoolJob {
        volatile gint32 state;
 };
 
-typedef void (*SgenThreadPoolThreadInitFunc) (void*);
-typedef void (*SgenThreadPoolIdleJobFunc) (void*);
-typedef gboolean (*SgenThreadPoolContinueIdleJobFunc) (void*);
-typedef gboolean (*SgenThreadPoolShouldWorkFunc) (void*);
+#define MAX_NUM_THREADS 8
+
+struct _SgenThreadPool {
+       mono_mutex_t lock;
+       mono_cond_t work_cond;
+       mono_cond_t done_cond;
+
+       int threads_num;
+       MonoNativeThreadId threads [MAX_NUM_THREADS];
+
+       /* Only accessed with the lock held. */
+       SgenPointerQueue job_queue;
+
+       SgenThreadPoolThreadInitFunc thread_init_func;
+       SgenThreadPoolIdleJobFunc idle_job_func;
+       SgenThreadPoolContinueIdleJobFunc continue_idle_job_func;
+       SgenThreadPoolShouldWorkFunc should_work_func;
+
+       volatile gboolean threadpool_shutdown;
+       volatile int threads_finished;
+};
+
+struct _SgenThreadPoolData {
+       SgenThreadPool *pool;
+};
 
-void sgen_thread_pool_init (int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, SgenThreadPoolShouldWorkFunc should_work_func, void **thread_datas);
+void sgen_thread_pool_init (SgenThreadPool *pool, int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, SgenThreadPoolShouldWorkFunc should_work_func, SgenThreadPoolData **thread_datas);
 
-void sgen_thread_pool_shutdown (void);
+void sgen_thread_pool_shutdown (SgenThreadPool *pool);
 
 SgenThreadPoolJob* sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size);
 /* This only needs to be called on jobs that are not enqueued. */
 void sgen_thread_pool_job_free (SgenThreadPoolJob *job);
 
-void sgen_thread_pool_job_enqueue (SgenThreadPoolJob *job);
+void sgen_thread_pool_job_enqueue (SgenThreadPool *pool, SgenThreadPoolJob *job);
 /* This must only be called after the job has been enqueued. */
-void sgen_thread_pool_job_wait (SgenThreadPoolJob *job);
+void sgen_thread_pool_job_wait (SgenThreadPool *pool, SgenThreadPoolJob *job);
 
-void sgen_thread_pool_idle_signal (void);
-void sgen_thread_pool_idle_wait (void);
+void sgen_thread_pool_idle_signal (SgenThreadPool *pool);
+void sgen_thread_pool_idle_wait (SgenThreadPool *pool);
 
-void sgen_thread_pool_wait_for_all_jobs (void);
+void sgen_thread_pool_wait_for_all_jobs (SgenThreadPool *pool);
 
-int sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId thread);
+int sgen_thread_pool_is_thread_pool_thread (SgenThreadPool *pool, MonoNativeThreadId thread);
 
 #endif
index f5169f45ab2e711c87ac1a59d41007ef8715b236..47fb00d9e1f8db39461cc62ff7a29c126ffedf61 100644 (file)
@@ -26,6 +26,9 @@ static volatile gboolean forced_stop;
 static WorkerData *workers_data;
 static SgenWorkerCallback worker_init_cb;
 
+static SgenThreadPool pool_inst;
+static SgenThreadPool *pool; /* null if we're not using workers */
+
 /*
  * When using multiple workers, we need to have the last worker
  * enqueue the preclean jobs (if there are any). This lock ensures
@@ -61,6 +64,8 @@ enum {
        STATE_WORK_ENQUEUED
 };
 
+#define SGEN_WORKER_MIN_SECTIONS_SIGNAL 4
+
 typedef gint32 State;
 
 static SgenObjectOperations * volatile idle_func_object_ops;
@@ -82,7 +87,7 @@ set_state (WorkerData *data, State old_state, State new_state)
        else if (new_state == STATE_WORKING)
                SGEN_ASSERT (0, old_state == STATE_WORK_ENQUEUED, "We can only transition to WORKING from WORK ENQUEUED");
        if (new_state == STATE_NOT_WORKING || new_state == STATE_WORKING)
-               SGEN_ASSERT (6, sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()), "Only the worker thread is allowed to transition to NOT_WORKING or WORKING");
+               SGEN_ASSERT (6, sgen_thread_pool_is_thread_pool_thread (pool, mono_native_thread_id_get ()), "Only the worker thread is allowed to transition to NOT_WORKING or WORKING");
 
        return InterlockedCompareExchange (&data->state, new_state, old_state) == old_state;
 }
@@ -126,7 +131,7 @@ sgen_workers_ensure_awake (void)
        }
 
        if (need_signal)
-               sgen_thread_pool_idle_signal ();
+               sgen_thread_pool_idle_signal (pool);
 }
 
 static void
@@ -198,24 +203,23 @@ sgen_workers_enqueue_job (SgenThreadPoolJob *job, gboolean enqueue)
                return;
        }
 
-       sgen_thread_pool_job_enqueue (job);
+       sgen_thread_pool_job_enqueue (pool, job);
 }
 
 static gboolean
 workers_get_work (WorkerData *data)
 {
-       SgenMajorCollector *major;
+       SgenMajorCollector *major = sgen_get_major_collector ();
+       SgenMinorCollector *minor = sgen_get_minor_collector ();
+       GrayQueueSection *section;
 
        g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));
+       g_assert (major->is_concurrent || minor->is_parallel);
 
-       /* If we're concurrent, steal from the workers distribute gray queue. */
-       major = sgen_get_major_collector ();
-       if (major->is_concurrent) {
-               GrayQueueSection *section = sgen_section_gray_queue_dequeue (&workers_distribute_gray_queue);
-               if (section) {
-                       sgen_gray_object_enqueue_section (&data->private_gray_queue, section, major->is_parallel);
-                       return TRUE;
-               }
+       section = sgen_section_gray_queue_dequeue (&workers_distribute_gray_queue);
+       if (section) {
+               sgen_gray_object_enqueue_section (&data->private_gray_queue, section, major->is_parallel);
+               return TRUE;
        }
 
        /* Nobody to steal from */
@@ -227,10 +231,13 @@ static gboolean
 workers_steal_work (WorkerData *data)
 {
        SgenMajorCollector *major = sgen_get_major_collector ();
+       SgenMinorCollector *minor = sgen_get_minor_collector ();
+       int generation = sgen_get_current_collection_generation ();
        GrayQueueSection *section = NULL;
        int i, current_worker;
 
-       if (!major->is_parallel)
+       if ((generation == GENERATION_OLD && !major->is_parallel) ||
+                       (generation == GENERATION_NURSERY && !minor->is_parallel))
                return FALSE;
 
        /* If we're parallel, steal from other workers' private gray queues  */
@@ -275,10 +282,11 @@ thread_pool_init_func (void *data_untyped)
 {
        WorkerData *data = (WorkerData *)data_untyped;
        SgenMajorCollector *major = sgen_get_major_collector ();
+       SgenMinorCollector *minor = sgen_get_minor_collector ();
 
        sgen_client_thread_register_worker ();
 
-       if (!major->is_concurrent)
+       if (!major->is_concurrent && !minor->is_parallel)
                return;
 
        init_private_gray_queue (data);
@@ -314,7 +322,6 @@ marker_idle_func (void *data_untyped)
        WorkerData *data = (WorkerData *)data_untyped;
 
        SGEN_ASSERT (0, continue_idle_func (data_untyped), "Why are we called when we're not supposed to work?");
-       SGEN_ASSERT (0, sgen_concurrent_collection_in_progress (), "The worker should only mark in concurrent collections.");
 
        if (data->state == STATE_WORK_ENQUEUED) {
                set_state (data, STATE_WORK_ENQUEUED, STATE_WORKING);
@@ -328,7 +335,8 @@ marker_idle_func (void *data_untyped)
 
                sgen_drain_gray_stack (ctx);
 
-               if (data->private_gray_queue.num_sections > 16 && workers_finished && worker_awakenings < active_workers_num) {
+               if (data->private_gray_queue.num_sections >= SGEN_WORKER_MIN_SECTIONS_SIGNAL
+                               && workers_finished && worker_awakenings < active_workers_num) {
                        /* We bound the number of worker awakenings just to be sure */
                        worker_awakenings++;
                        mono_os_mutex_lock (&finished_lock);
@@ -357,7 +365,7 @@ init_distribute_gray_queue (void)
 void
 sgen_workers_init_distribute_gray_queue (void)
 {
-       SGEN_ASSERT (0, sgen_get_major_collector ()->is_concurrent,
+       SGEN_ASSERT (0, sgen_get_major_collector ()->is_concurrent || sgen_get_minor_collector ()->is_parallel,
                        "Why should we init the distribute gray queue if we don't need it?");
        init_distribute_gray_queue ();
 }
@@ -366,12 +374,7 @@ void
 sgen_workers_init (int num_workers, SgenWorkerCallback callback)
 {
        int i;
-       void **workers_data_ptrs = (void **)alloca(num_workers * sizeof(void *));
-
-       if (!sgen_get_major_collector ()->is_concurrent) {
-               sgen_thread_pool_init (num_workers, thread_pool_init_func, NULL, NULL, NULL, NULL);
-               return;
-       }
+       WorkerData **workers_data_ptrs = (WorkerData**)alloca(num_workers * sizeof(WorkerData*));
 
        mono_os_mutex_init (&finished_lock);
        //g_print ("initing %d workers\n", num_workers);
@@ -385,15 +388,23 @@ sgen_workers_init (int num_workers, SgenWorkerCallback callback)
        init_distribute_gray_queue ();
 
        for (i = 0; i < num_workers; ++i)
-               workers_data_ptrs [i] = (void *) &workers_data [i];
+               workers_data_ptrs [i] = &workers_data [i];
 
        worker_init_cb = callback;
 
-       sgen_thread_pool_init (num_workers, thread_pool_init_func, marker_idle_func, continue_idle_func, should_work_func, workers_data_ptrs);
+       pool = &pool_inst;
+       sgen_thread_pool_init (pool, num_workers, thread_pool_init_func, marker_idle_func, continue_idle_func, should_work_func, (SgenThreadPoolData**)workers_data_ptrs);
 
        mono_counters_register ("# workers finished", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_workers_num_finished);
 }
 
+void
+sgen_workers_shutdown (void)
+{
+       if (pool)
+               sgen_thread_pool_shutdown (pool);
+}
+
 void
 sgen_workers_stop_all_workers (void)
 {
@@ -401,8 +412,8 @@ sgen_workers_stop_all_workers (void)
        mono_memory_write_barrier ();
        forced_stop = TRUE;
 
-       sgen_thread_pool_wait_for_all_jobs ();
-       sgen_thread_pool_idle_wait ();
+       sgen_thread_pool_wait_for_all_jobs (pool);
+       sgen_thread_pool_idle_wait (pool);
        SGEN_ASSERT (0, sgen_workers_all_done (), "Can only signal enqueue work when in no work state");
 }
 
@@ -441,8 +452,8 @@ sgen_workers_join (void)
 {
        int i;
 
-       sgen_thread_pool_wait_for_all_jobs ();
-       sgen_thread_pool_idle_wait ();
+       sgen_thread_pool_wait_for_all_jobs (pool);
+       sgen_thread_pool_idle_wait (pool);
        SGEN_ASSERT (0, sgen_workers_all_done (), "Can only signal enqueue work when in no work state");
 
        /* At this point all the workers have stopped. */
@@ -541,4 +552,12 @@ sgen_workers_foreach (SgenWorkerCallback callback)
                callback (&workers_data [i]);
 }
 
+gboolean
+sgen_workers_is_worker_thread (MonoNativeThreadId id)
+{
+       if (!pool)
+               return FALSE;
+       return sgen_thread_pool_is_thread_pool_thread (pool, id);
+}
+
 #endif
index e2f030dc159135210d50d80fd1e60a5799e7291a..78dea19867d645d76b7fe73dfcf81c04981da7a2 100644 (file)
 
 typedef struct _WorkerData WorkerData;
 struct _WorkerData {
+       /*
+        * Threadpool threads receive as their starting argument a WorkerData.
+        * tp_data is meant for use inside the sgen thread pool and must be first.
+        */
+       SgenThreadPoolData tp_data;
        gint32 state;
        SgenGrayQueue private_gray_queue; /* only read/written by worker thread */
        /*
@@ -30,6 +35,7 @@ typedef void (*SgenWorkersFinishCallback) (void);
 typedef void (*SgenWorkerCallback) (WorkerData *data);
 
 void sgen_workers_init (int num_workers, SgenWorkerCallback callback);
+void sgen_workers_shutdown (void);
 void sgen_workers_stop_all_workers (void);
 void sgen_workers_set_num_active_workers (int num_workers);
 void sgen_workers_start_all_workers (SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback finish_job);
@@ -46,5 +52,6 @@ void sgen_workers_take_from_queue (SgenGrayQueue *queue);
 SgenObjectOperations* sgen_workers_get_idle_func_object_ops (void);
 int sgen_workers_get_job_split_count (void);
 void sgen_workers_foreach (SgenWorkerCallback callback);
+gboolean sgen_workers_is_worker_thread (MonoNativeThreadId id);
 
 #endif
index 71a0d8d62577fff3eba913fe17b1a65e7514d338..a1d0d0ebcd3081341a7821c44b447642b8889b00 100644 (file)
@@ -59,6 +59,7 @@ mono_check_mode_enabled (MonoCheckMode query)
 #endif
                        }
                        g_strfreev (env_split);
+                       g_free (env_string);
                }
 
                check_mode = env_check_mode;
@@ -72,10 +73,12 @@ mono_check_transition_limit (void)
        static int transition_limit = -1;
        if (transition_limit < 0) {
                const gchar *env_string = g_getenv ("MONO_CHECK_THREAD_TRANSITION_HISTORY");
-               if (env_string)
+               if (env_string) {
                        transition_limit = atoi (env_string);
-               else
+                       g_free (env_string);
+               } else {
                        transition_limit = 3;
+               }
        }
        return transition_limit;
 }
index 9d5722e33a1be79c5e67a36369b814bf4ece1811..c0e68ee034fffc8368b0ce06660a2f9ae4eadcd6 100644 (file)
@@ -34,8 +34,8 @@ static gboolean hwcap_inited = FALSE;
 void
 mono_hwcap_init (void)
 {
-       const char *verbose = g_getenv ("MONO_VERBOSE_HWCAP");
-       const char *conservative = g_getenv ("MONO_CONSERVATIVE_HWCAP");
+       char *verbose = g_getenv ("MONO_VERBOSE_HWCAP");
+       char *conservative = g_getenv ("MONO_CONSERVATIVE_HWCAP");
 
        if (hwcap_inited)
                return;
@@ -45,6 +45,9 @@ mono_hwcap_init (void)
 
        if (verbose && !strncmp (verbose, "1", 1))
                mono_hwcap_print ();
+
+       g_free (verbose);
+       g_free (conservative);
 }
 
 void
index abbe812f5928d6ea6a83795111dbd928f0da9bc2..b164b6b56db21e607b97501f5855bc9b79660bdf 100644 (file)
@@ -23,7 +23,7 @@ static inline gchar *mono_portability_find_file_internal (GString **report, cons
 
 void mono_portability_helpers_init (void)
 {
-        const gchar *env;
+        gchar *env;
 
        if (mono_io_portability_helpers != PORTABILITY_UNKNOWN)
                return;
@@ -56,6 +56,7 @@ void mono_portability_helpers_init (void)
                                 mono_io_portability_helpers |= (PORTABILITY_DRIVE | PORTABILITY_CASE);
                        }
                 }
+               g_free (env);
        }
 }
 
index 6590cb54bdcae62b31fe2cb216c6f94ab3a24687..dd20f86b138618eba103b430fac6ca15d20286f5 100644 (file)
@@ -107,19 +107,20 @@ mono_log_write_logfile (const char *log_domain, GLogLevelFlags level, mono_bool
                pid_t pid;
                char logTime [80];
 
-#ifndef HOST_WIN32
+#ifdef HAVE_LOCALTIME_R
                struct tm tod;
                time(&t);
                localtime_r(&t, &tod);
-               pid = getpid();
                strftime(logTime, sizeof(logTime), "%Y-%m-%d %H:%M:%S", &tod);
 #else
                struct tm *tod;
                time(&t);
                tod = localtime(&t);
-               pid = mono_process_current_pid ();
                strftime(logTime, sizeof(logTime), "%F %T", tod);
 #endif
+
+               pid = mono_process_current_pid ();
+
                fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
        } else {
                fprintf (logFile, "%s%s%s\n",
index 4b32dfb0334b17fe02402fde748554536f770b1b..aeaa3f97ceefab0bc79fe685d042ade9a91d5368 100644 (file)
@@ -47,10 +47,20 @@ mono_trace_init (void)
                mono_internal_current_level = G_LOG_LEVEL_ERROR;
                level_stack = g_queue_new();
 
-               mono_trace_set_mask_string(g_getenv("MONO_LOG_MASK"));
-               mono_trace_set_level_string(g_getenv("MONO_LOG_LEVEL"));
-               mono_trace_set_logheader_string(g_getenv("MONO_LOG_HEADER"));
-               mono_trace_set_logdest_string(g_getenv("MONO_LOG_DEST"));
+               char *mask = g_getenv ("MONO_LOG_MASK");
+               char *level = g_getenv ("MONO_LOG_LEVEL");
+               char *header = g_getenv ("MONO_LOG_HEADER");
+               char *dest = g_getenv ("MONO_LOG_DEST");
+
+               mono_trace_set_mask_string(mask);
+               mono_trace_set_level_string(level);
+               mono_trace_set_logheader_string(header);
+               mono_trace_set_logdest_string(dest);
+
+               g_free (mask);
+               g_free (level);
+               g_free (header);
+               g_free (dest);
        }
 }
 
index b5e2ee2757d8df361f2d6be23da71166b745b881..4bd214d4dddc26787ab4c8c702c5cf667f74a08e 100644 (file)
@@ -424,7 +424,7 @@ static gboolean
 shared_area_disabled (void)
 {
        if (!use_shared_area) {
-               if (g_getenv ("MONO_DISABLE_SHARED_AREA"))
+               if (g_hasenv ("MONO_DISABLE_SHARED_AREA"))
                        use_shared_area = -1;
                else
                        use_shared_area = 1;
index 6b2bb98eef90e81d7b6e9a95a063d4f31e076482..13b8a32393716ec9473ce9d9e4bbd9ef6e849087 100644 (file)
@@ -136,7 +136,7 @@ mono_rand_open (void)
                file = open (NAME_DEV_RANDOM, O_RDONLY);
 #endif
        if (file < 0)
-               use_egd = g_getenv("MONO_EGD_SOCKET") != NULL;
+               use_egd = g_hasenv ("MONO_EGD_SOCKET");
 
        status = 2;
 
@@ -158,13 +158,14 @@ mono_rand_try_get_bytes (gpointer *handle, guchar *buffer, gint buffer_size, Mon
        error_init (error);
 
        if (use_egd) {
-               const char *socket_path = g_getenv ("MONO_EGD_SOCKET");
+               char *socket_path = g_getenv ("MONO_EGD_SOCKET");
                /* exception will be thrown in managed code */
                if (socket_path == NULL) {
                        *handle = NULL;
                        return FALSE;
                }
                get_entropy_from_egd (socket_path, buffer, buffer_size, error);
+               g_free (socket_path);
        } else {
                /* Read until the buffer is filled. This may block if using NAME_DEV_RANDOM. */
                gint count = 0;
index c7ad2cedd416318e210e14ebcaebb3134b3ba431..0d5f1e9b73577e3ce129005e5dedf4de73dc3972 100644 (file)
@@ -430,7 +430,7 @@ mono_threads_is_coop_enabled (void)
 #else
        static int is_coop_enabled = -1;
        if (G_UNLIKELY (is_coop_enabled == -1))
-               is_coop_enabled = g_getenv ("MONO_ENABLE_COOP") != NULL ? 1 : 0;
+               is_coop_enabled = g_hasenv ("MONO_ENABLE_COOP") ? 1 : 0;
        return is_coop_enabled == 1;
 #endif
 }
index ddc0a02ac183c904def40e251be8f4697fd3f31e..e6d151ce2566c841cfdba4ae8d1f083d30bfcfa6 100644 (file)
@@ -681,7 +681,7 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
        gboolean res;
        threads_callbacks = *callbacks;
        thread_info_size = info_size;
-       const char *sleepLimit;
+       char *sleepLimit;
 #ifdef HOST_WIN32
        res = mono_native_tls_alloc (&thread_info_key, NULL);
        res = mono_native_tls_alloc (&thread_exited_key, NULL);
@@ -705,6 +705,7 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
                        sleepWarnDuration = threshold / 20;
                } else
                        g_warning("MONO_SLEEP_ABORT_LIMIT must be a number >= 40");
+               g_free (sleepLimit);
        }
 
        mono_os_sem_init (&global_suspend_semaphore, 1);
index 9dd245e29cc21af0c7a8088303dcb6ba0034f66b..2ece0733d122a42d8ac969a7027081faf6af501a 100644 (file)
@@ -45,7 +45,7 @@ mono_unicode_from_external (const gchar *in, gsize *bytes)
 {
        gchar *res=NULL;
        gchar **encodings;
-       const gchar *encoding_list;
+       gchar *encoding_list;
        int i;
        glong lbytes;
        
@@ -55,10 +55,11 @@ mono_unicode_from_external (const gchar *in, gsize *bytes)
        
        encoding_list=g_getenv ("MONO_EXTERNAL_ENCODINGS");
        if(encoding_list==NULL) {
-               encoding_list = "";
+               encoding_list = g_strdup("");
        }
        
        encodings=g_strsplit (encoding_list, ":", 0);
+       g_free (encoding_list);
        for(i=0;encodings[i]!=NULL; i++) {
                /* "default_locale" is a special case encoding */
                if(!strcmp (encodings[i], "default_locale")) {
@@ -118,7 +119,7 @@ gchar *mono_utf8_from_external (const gchar *in)
 {
        gchar *res=NULL;
        gchar **encodings;
-       const gchar *encoding_list;
+       gchar *encoding_list;
        int i;
        
        if(in==NULL) {
@@ -127,10 +128,11 @@ gchar *mono_utf8_from_external (const gchar *in)
        
        encoding_list=g_getenv ("MONO_EXTERNAL_ENCODINGS");
        if(encoding_list==NULL) {
-               encoding_list = "";
+               encoding_list = g_strdup("");
        }
        
        encodings=g_strsplit (encoding_list, ":", 0);
+       g_free (encoding_list);
        for(i=0;encodings[i]!=NULL; i++) {
                
                /* "default_locale" is a special case encoding */
@@ -171,7 +173,7 @@ gchar *mono_utf8_from_external (const gchar *in)
 gchar *mono_unicode_to_external (const gunichar2 *uni)
 {
        gchar *utf8;
-       const gchar *encoding_list;
+       gchar *encoding_list;
        
        /* Turn the unicode into utf8 to start with, because its
         * easier to work with gchar * than gunichar2 *
@@ -188,6 +190,7 @@ gchar *mono_unicode_to_external (const gunichar2 *uni)
                int i;
                
                encodings=g_strsplit (encoding_list, ":", 0);
+               g_free (encoding_list);
                for(i=0; encodings[i]!=NULL; i++) {
                        if(!strcmp (encodings[i], "default_locale")) {
                                res=g_locale_from_utf8 (utf8, -1, NULL, NULL,
index 08a0c5d7da18ddd8d9e3d737e6e3ffc68ead74e2..58fddbc742bb2132b78e3af4468fdbb244b4d396 100755 (executable)
@@ -3,5 +3,6 @@
 export TESTCMD=`dirname "${BASH_SOURCE[0]}"`/run-step.sh
 
 ${TESTCMD} --label=interpreter-regression --timeout=10m make -C mono/mini richeck
+${TESTCMD} --label=mixedmode-regression --timeout=10m make -C mono/mini mixedcheck
 ${TESTCMD} --label=compile-runtime-tests --timeout=40m make -w -C mono/tests -j4 tests
 ${TESTCMD} --label=runtime-interp --timeout=160m make -w -C mono/tests -k testinterp V=1