Merge pull request #3345 from alexanderkyte/fix_mini_aot_flags
authorAlexander Kyte <alexmkyte@gmail.com>
Mon, 1 Aug 2016 21:17:07 +0000 (17:17 -0400)
committerGitHub <noreply@github.com>
Mon, 1 Aug 2016 21:17:07 +0000 (17:17 -0400)
[runtime] Pass invariant AOT options to mini aot tests

151 files changed:
Makefile.am
acceptance-tests/roslyn.mk
configure.ac
man/mono.1
mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/Makefile
mcs/class/Facades/System.Data.Common/Makefile
mcs/class/Facades/System.Diagnostics.StackTrace/Makefile
mcs/class/Facades/System.Diagnostics.Tracing/Makefile
mcs/class/Facades/System.Globalization.Extensions/Makefile
mcs/class/Facades/System.IO.Compression/AssemblyInfo.cs [deleted file]
mcs/class/Facades/System.IO.Compression/Makefile [deleted file]
mcs/class/Facades/System.IO.Compression/Missing.cs [deleted file]
mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources [deleted file]
mcs/class/Facades/System.IO.Compression/TypeForwarders.cs [deleted file]
mcs/class/Facades/System.IO.FileSystem.AccessControl/Makefile
mcs/class/Facades/System.Net.Sockets/Makefile
mcs/class/Facades/System.Reflection.TypeExtensions/Makefile
mcs/class/Facades/System.Runtime.Serialization.Primitives/Makefile
mcs/class/Facades/System.Runtime.Serialization.Xml/Makefile
mcs/class/Facades/System.Security.Cryptography.Algorithms/Makefile
mcs/class/Facades/System.Security.Cryptography.OpenSsl/Makefile
mcs/class/Facades/System.Security.SecureString/Makefile
mcs/class/Facades/System.ServiceModel.Primitives/Makefile
mcs/class/Facades/System.ServiceProcess.ServiceController/Makefile
mcs/class/Facades/System.Text.Encoding.CodePages/CodePagesEncodingProvider.cs
mcs/class/Facades/System.Text.Encoding.CodePages/Makefile
mcs/class/Facades/System.Threading.AccessControl/Makefile
mcs/class/Facades/System.Threading.Overlapped/Makefile
mcs/class/Facades/System.Xml.XPath.XDocument/Makefile
mcs/class/Facades/subdirs.make
mcs/class/Mono.Debugger.Soft/Makefile
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/Mono.Security/monodroid_Mono.Security_test.dll.exclude.sources
mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs
mcs/class/System.Core/common_System.Core.dll.sources
mcs/class/System.Data/Microsoft.SqlServer.Server/SqlDataRecord.cs
mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs
mcs/class/System/Mono.Net.Security/SystemCertificateValidator.cs
mcs/class/System/System.Diagnostics/ProcessModuleCollection.cs
mcs/class/System/System.Diagnostics/ProcessThreadCollection.cs
mcs/class/System/Test/System.Net.Mail/SmtpClientTest.cs
mcs/class/System/Test/System.Net.Security/SslStreamTest.cs
mcs/class/System/Test/System.Net.Sockets/NetworkStreamTest.cs
mcs/class/System/Test/System.Net.Sockets/SocketAcceptAsyncTest.cs
mcs/class/System/Test/System.Net.Sockets/SocketAsyncTest.cs
mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
mcs/class/System/Test/System.Net.Sockets/TcpClientTest.cs
mcs/class/System/Test/System.Net.Sockets/TcpListenerTest.cs
mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs
mcs/class/System/Test/System.Net/CookieParserTest.cs
mcs/class/System/Test/System.Net/DnsTest.cs
mcs/class/System/Test/System.Net/FileWebRequestTest.cs
mcs/class/System/Test/System.Net/FtpWebRequestTest.cs
mcs/class/System/Test/System.Net/HttpListener2Test.cs
mcs/class/System/Test/System.Net/HttpListenerPrefixCollectionTest.cs
mcs/class/System/Test/System.Net/HttpListenerRequestTest.cs
mcs/class/System/Test/System.Net/HttpListenerTest.cs
mcs/class/System/Test/System.Net/HttpWebRequestTest.cs
mcs/class/System/Test/System.Net/HttpWebResponseTest.cs
mcs/class/System/Test/System.Net/WebClientTest.cs
mcs/class/System/Test/System.Net/WebRequestTest.cs
mcs/class/corlib/Mono/RuntimeHandles.cs
mcs/class/corlib/Mono/RuntimeMarshal.cs [new file with mode: 0644]
mcs/class/corlib/Mono/RuntimeStructs.cs
mcs/class/corlib/Mono/SafeGPtrArrayHandle.cs
mcs/class/corlib/Mono/SafeStringMarshal.cs [new file with mode: 0644]
mcs/class/corlib/ReferenceSources/RuntimeType.cs
mcs/class/corlib/System.IO/File.cs
mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs
mcs/class/corlib/System.Reflection/Assembly.cs
mcs/class/corlib/System.Reflection/AssemblyName.cs
mcs/class/corlib/System.Reflection/MonoAssembly.cs
mcs/class/corlib/System.Runtime.CompilerServices/ConditionalWeakTable.cs
mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/corlib.dll.sources
mcs/errors/cs0163-2.cs [new file with mode: 0644]
mcs/errors/cs1644-50.cs [new file with mode: 0644]
mcs/mcs/assign.cs
mcs/mcs/class.cs
mcs/mcs/cs-parser.jay
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/statement.cs
mcs/tests/gtest-lambda-37.cs [new file with mode: 0644]
mcs/tests/test-938.cs [new file with mode: 0644]
mcs/tests/test-async-86.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml
mcs/tools/corcompare/mono-api-info.cs
mcs/tools/linker/Descriptors/mscorlib.xml
mcs/tools/mono-api-html/MemberComparer.cs
mono/io-layer/io.c
mono/io-layer/processes.c
mono/io-layer/shared.c
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/boehm-gc.c
mono/metadata/gc-internals.h
mono/metadata/gc.c
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/mono-debug.c
mono/metadata/mono-debug.h
mono/metadata/null-gc.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/remoting.c
mono/metadata/remoting.h
mono/metadata/sgen-mono.c
mono/metadata/threadpool-ms.c
mono/metadata/threads.c
mono/metadata/wrapper-types.h
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/debug-mini.c
mono/mini/debugger-agent.c
mono/mini/mini-arm.c
mono/mini/mini-runtime.c
mono/mini/mini-trampolines.c
mono/mini/mini.h
mono/mini/tasklets.c
mono/sgen/sgen-copy-object.h
mono/sgen/sgen-debug.c
mono/sgen/sgen-fin-weak-hash.c
mono/sgen/sgen-gc.c
mono/sgen/sgen-gc.h
mono/sgen/sgen-gray.c
mono/sgen/sgen-gray.h
mono/sgen/sgen-los.c
mono/sgen/sgen-marksweep.c
mono/sgen/sgen-minor-copy-object.h
mono/sgen/sgen-minor-scan-object.h
mono/sgen/sgen-protocol.c
mono/sgen/sgen-protocol.h
mono/sgen/sgen-simple-nursery.c
mono/sgen/sgen-split-nursery.c
mono/sgen/sgen-workers.c
mono/sgen/sgen-workers.h
mono/utils/mono-coop-mutex.h
mono/utils/mono-coop-semaphore.h
mono/utils/mono-hwcap-arm.c
mono/utils/mono-os-mutex.h
mono/utils/mono-os-semaphore.h
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/w32handle.c
scripts/ci/run-jenkins.sh
scripts/ci/run-test-acceptance-tests.sh [new file with mode: 0755]
scripts/ci/run-test-default.sh

index 9c6dc7e971457668dc80b31fa3d5d152d9b3f363..aaffb9842ba9dbe36090cead00afe0d1ebe1232d 100644 (file)
@@ -67,9 +67,13 @@ get-monolite-latest:
        cd $(mcslib) && { (wget -O- $(monolite_url) || curl $(monolite_url)) | gzip -d | tar xf - ; }
        cd $(mcslib) && mv -f monolite-* monolite
 
+if BITCODE
+BITCODE_CHECK=yes
+endif
+
 .PHONY: check-ci
 check-ci:
-       MONO_LLVMONLY=$(MONO_LLVMONLY) $(srcdir)/scripts/ci/run-test-$(TEST_PROFILE).sh
+       MONO_LLVMONLY=$(BITCODE_CHECK) $(srcdir)/scripts/ci/run-test-$(TEST_PROFILE).sh
 
 .PHONY: validate do-build-mono-mcs mcs-do-clean mcs-do-tests
 validate: do-build-mono-mcs
index fbfa2760ec2744588adbfb251e67a2a4adf3ae23..a91c68d986b5a97720963c05258a82354cc7efa8 100644 (file)
@@ -4,17 +4,11 @@ check-roslyn:
        sed -i -e 's/\\4.5-api"/\\4.5"/g' $$PREFIX/lib/mono/xbuild-frameworks/.NETFramework/v4.5/RedistList/FrameworkList.xml; \
        export MSBuildExtensionsPath=$$PREFIX/lib/mono/xbuild; \
        MONO_DOTNET_PORTABLE_DIR=$$PREFIX/lib/mono/xbuild-frameworks/.NETPortable/; \
-       MONO_NUGET_TARGETS_DIR=$$PREFIX/lib/mono/xbuild/Microsoft/NuGet/; \
-       MONO_PORTABLE_TARGETS_DIR=$$PREFIX/lib/mono/xbuild/Microsoft/Portable/v5.0; \
-       if [ ! -d "$$MONO_DOTNET_PORTABLE_DIR/v5.0" ]; then \
+       if [ ! -d "$$MONO_DOTNET_PORTABLE_DIR/v4.6" ]; then \
                mkdir -p $$MONO_DOTNET_PORTABLE_DIR; \
-               mkdir -p $$MONO_NUGET_TARGETS_DIR; \
-               mkdir -p $$MONO_PORTABLE_TARGETS_DIR; \
                curl -SL "http://download.mono-project.com/third-party/RoslynBuildDependencies.zip" > /tmp/RoslynBuildDependencies.zip; \
                unzip -o /tmp/RoslynBuildDependencies.zip -d /tmp/RoslynBuildDependencies; \
                cp -r /tmp/RoslynBuildDependencies/PortableReferenceAssemblies/* $$MONO_DOTNET_PORTABLE_DIR; \
-               cp /tmp/RoslynBuildDependencies/NuGetTargets/* $$MONO_NUGET_TARGETS_DIR; \
-               cp /tmp/RoslynBuildDependencies/PortableTargets/* $$MONO_PORTABLE_TARGETS_DIR; \
        fi; \
        cd $(ROSLYN_PATH); \
        sed -i -e 'N; s/bootstrapArg=".*\n.*"/bootstrapArg=""/g' cibuild.sh; \
index ddc88912bdd9d3f47e4ed8c3da903303f8de9b9e..924acc99cdbbc681fa194f859aa9fc50b36e8dea 100644 (file)
@@ -2,7 +2,7 @@
 #AC_PREREQ([2.62])
 
 # when bumping version number below, keep it in sync with man/mono.1 too
-AC_INIT(mono, [4.5.2],
+AC_INIT(mono, [4.7.0],
         [http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono])
 
 AC_CONFIG_SRCDIR([README.md])
@@ -532,6 +532,9 @@ if test x"$GCC" = xyes; then
                # We rely on signed overflow to behave
                CFLAGS="$CFLAGS -fwrapv"
 
+               # We rely on zero length arrays in structs
+               CFLAGS="$CFLAGS -Wno-zero-length-array"
+
                CFLAGS="$CFLAGS -DMONO_DLL_EXPORT"
                if test x"$disable_visibility_hidden" = xno; then
                   # Don't export any symbols by default
@@ -894,8 +897,6 @@ AM_CONDITIONAL(INSTALL_MOBILE_STATIC, [test "x$with_mobile_static" != "xno"])
 
 AC_SUBST(INSTALL_MOBILE_STATIC)
 
-AC_SUBST(BITCODE)
-
 default_profile=net_4_x
 if test -z "$INSTALL_MONODROID_TRUE"; then :
    default_profile=monodroid
index 81f5ae9838987a1805e1d9bcb175bc758af330e0..c4589ea70c7243f74525d5669f342c983f24f39b 100644 (file)
@@ -7,7 +7,7 @@
 .\" Author:
 .\"   Miguel de Icaza (miguel@gnu.org)
 .\"
-.TH Mono "Mono 4.5.2"
+.TH Mono "Mono 4.7.0"
 .SH NAME
 mono \- Mono's ECMA-CLI native code generator (Just-in-Time and Ahead-of-Time)
 .SH SYNOPSIS
@@ -1100,7 +1100,7 @@ a Mono process through the environment.   This is useful for example
 to force all of your Mono processes to use LLVM or SGEN without having
 to modify any launch scripts.
 .TP
-\fBMONO_ENV_OPTIONS\fR
+\fBMONO_SDB_ENV_OPTIONS\fR
 Used to pass extra options to the debugger agent in the runtime, as they were passed
 using --debugger-agent=.
 .TP
@@ -1302,12 +1302,12 @@ statistics when shutting down.
 .TP
 \fBcollect-before-allocs\fR
 .TP
-\fBcheck-at-minor-collections\fR
-This performs a consistency check on minor collections and also clears
-the nursery at collection time, instead of the default, when buffers
-are allocated (clear-at-gc).   The consistency check ensures that
-there are no major to minor references that are not on the remembered
-sets. 
+\fBcheck-remset-consistency\fR
+This performs a remset consistency check at various opportunities, and
+also clears the nursery at collection time, instead of the default,
+when buffers are allocated (clear-at-gc).  The consistency check
+ensures that there are no major to minor references that are not on
+the remembered sets.
 .TP
 \fBmod-union-consistency-check\fR
 Checks that the mod-union cardtable is consistent before each
index 0b5f4acf6daad43a1597f99ada62b9ebd4f05fc2..4197137c95ee1093c968bb85209da78202287b9a 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index ff6d03567897533cc1b43a22bd216a4bcecea509..fe63a8e0f7b1c2feb776fc73b0f8bef97e5c2e9b 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System System.Data System.Xml
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 25d8ac37eddd1351ee41e37670615d9b8df46531..4cc9d7f1a3bee21d447328e91d858fef184fcbc3 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 14b380da866454c7569c53a115dfa4e473422415..d74812c5e9f37df4cb06b1a044a3b67932b01081 100644 (file)
@@ -13,8 +13,6 @@ KEY_FILE = ../../msfinal.pub
 SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index d3a57fa307dbd8b7121b25630aa667270b3dc640..446a41276071919f313a88018b1ef9cb6b6aeb89 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
diff --git a/mcs/class/Facades/System.IO.Compression/AssemblyInfo.cs b/mcs/class/Facades/System.IO.Compression/AssemblyInfo.cs
deleted file mode 100644 (file)
index 08e157f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// 
-// 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;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-[assembly: AssemblyTitle ("System.IO.Compression.dll")]
-[assembly: AssemblyDescription ("System.IO.Compression.dll")]
-[assembly: AssemblyDefaultAlias ("System.IO.Compression.dll")]
-[assembly: AssemblyCompany ("Xamarin, Inc.")]
-[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
-[assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
-[assembly: AssemblyInformationalVersion ("4.0.0.0")]
-[assembly: AssemblyFileVersion ("4.0.0.0")]
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../../msfinal.pub")]
-
-[assembly: ReferenceAssembly]
-
-
diff --git a/mcs/class/Facades/System.IO.Compression/Makefile b/mcs/class/Facades/System.IO.Compression/Makefile
deleted file mode 100644 (file)
index 4fbfc56..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-MCS_BUILD_DIR = ../../../build
-
-thisdir = class/Facades/System.IO.Compression
-SUBDIRS = 
-include $(MCS_BUILD_DIR)/rules.make
-
-LIBRARY_SUBDIR = Facades
-LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
-
-LIBRARY = System.IO.Compression.dll
-
-KEY_FILE = ../../msfinal.pub
-SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS)
-
-PLATFORM_DEBUG_FLAGS =
-
-NO_TEST = yes
-
-include $(MCS_BUILD_DIR)/library.make
-
-
diff --git a/mcs/class/Facades/System.IO.Compression/Missing.cs b/mcs/class/Facades/System.IO.Compression/Missing.cs
deleted file mode 100644 (file)
index cd06b1c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// This is stub only. The implementation should come from https://github.com/dotnet/corefx/tree/master/src/System.IO.Compression/src/System/IO/Compression
-
-namespace System.IO.Compression
-{
-       public class ZipArchive : System.IDisposable
-       {
-               public ZipArchive(System.IO.Stream stream) { }
-               public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode) { }
-               public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) { }
-               public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding entryNameEncoding) { }
-               public System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry> Entries { get { return default(System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry>); } }
-               public System.IO.Compression.ZipArchiveMode Mode { get { return default(System.IO.Compression.ZipArchiveMode); } }
-               public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName) { return default(System.IO.Compression.ZipArchiveEntry); }
-               public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName, System.IO.Compression.CompressionLevel compressionLevel) { return default(System.IO.Compression.ZipArchiveEntry); }
-               public void Dispose() { }
-               protected virtual void Dispose(bool disposing) { }
-               public System.IO.Compression.ZipArchiveEntry GetEntry(string entryName) { return default(System.IO.Compression.ZipArchiveEntry); }
-       }
-
-       public partial class ZipArchiveEntry
-       {
-               internal ZipArchiveEntry() { }
-               public System.IO.Compression.ZipArchive Archive { get { return default(System.IO.Compression.ZipArchive); } }
-               public long CompressedLength { get { return default(long); } }
-               public string FullName { get { return default(string); } }
-               public System.DateTimeOffset LastWriteTime { get { return default(System.DateTimeOffset); } set { } }
-               public long Length { get { return default(long); } }
-               public string Name { get { return default(string); } }
-               public void Delete() { }
-               public System.IO.Stream Open() { return default(System.IO.Stream); }
-               public override string ToString() { return default(string); }
-       }
-
-       public enum ZipArchiveMode
-       {
-               Create = 1,
-               Read = 0,
-               Update = 2,
-       }
-}
\ No newline at end of file
diff --git a/mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources b/mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources
deleted file mode 100644 (file)
index 402d066..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-TypeForwarders.cs
-AssemblyInfo.cs
-Missing.cs
diff --git a/mcs/class/Facades/System.IO.Compression/TypeForwarders.cs b/mcs/class/Facades/System.IO.Compression/TypeForwarders.cs
deleted file mode 100644 (file)
index 5eaf037..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// 
-// 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.
-// 
-
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Compression.CompressionLevel))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Compression.CompressionMode))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Compression.DeflateStream))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Compression.GZipStream))]
-
-
index 0198747a8a312def61d8cb153e45a6b6d038c168..9efb35542bf8ec2e85c7c8d94db0df651674a675 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index bf60d5fef6be2147d79b9b70e5ab29430dc1f651..497c05462276fee5be2ca4b18564dd8e33947548 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index b2bb49ecfd1b431029d66f45927f36d0e712e26b..374132468e61aebb09604f1e0bac3efe928001f5 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 3a2519549fc638191e38dad30136d69222edbd3a..22a0d90aae49b611b513e31f72ce4ffeaaa5f728 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System.Runtime.Serialization
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index dc0a84d022933675423cf9435280d42f3c277367..1314e94f39d484616a65c08ba57297e6246479c9 100644 (file)
@@ -18,8 +18,6 @@ ifeq (2.1, $(FRAMEWORK_VERSION))
 LIB_MCS_FLAGS += /d:NO_CODEDOM
 endif
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 389a11cf6cf8d9fa9e39ee2c4fb4774bc2492247..e65ee83c7ab30a2f44656292ed9f44752a5c7e76 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System System.Core
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index aa30bc935a1fa9edc82dcdfbb086c835ce394ef4..16bae2df174a282a1cf8fa44b26fca8819a1ad21 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System.Core
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index b33d20dc20261912e900021303cca36c3d41bda3..0569f621974fbf469b5148d5f814caefbeb7aea6 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index b89ba3525c8652877cf796a1b56edf2c72a59ed2..3c12456831dcfa7317f2aff4f559a6628a26463a 100644 (file)
@@ -19,8 +19,6 @@ endif
 
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 5fa4c609b0ba9bf81b857a8c688e79cfb7f3ae6f..fe6edb861f243350862241c72bc293d517f30973 100644 (file)
@@ -21,8 +21,6 @@ endif
 
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index d97ad54eb89f246a0302e5b6234e5a3356dd65c7..0933eeef41282d83d6e96fc24774e38d511a0d14 100644 (file)
 
 namespace System.Text
 {
-       public sealed partial class CodePagesEncodingProvider
+       public sealed class CodePagesEncodingProvider : EncodingProvider
        {
+               static readonly CodePagesEncodingProvider instance = new CodePagesEncodingProvider ();
+
                private CodePagesEncodingProvider ()
                {
                }
                
-               public static System.Text.EncodingProvider Instance { 
+               public static EncodingProvider Instance {
                        get {
-                               throw new NotImplementedException ();
+                               return instance;
                        }
                }
+
+               public override Encoding GetEncoding (string name)
+               {
+                       // MSDN: "if name is not the name of an encoding that you support, the method should return null."
+                       // We do this here since all our encodings are already supported by the main Encoding class
+                       return null;
+               }
+
+               public override Encoding GetEncoding (int codepage)
+               {
+                       // MSDN: "if codepage is not the code page identifier of an encoding that you support, the method should return null."
+                       // We do this here since all our encodings are already supported by the main Encoding class
+                       return null;
+               }
        }
 }
\ No newline at end of file
index 7430a65175bafb63ac8b52e73c0071d905119781..3c678ee54f79b3d041ffb587dd4ab90c7ed5edd9 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index b0c9264a03b466ee7b50290b3c4b12b5fb140b92..a5de66c999827fa2f60998ed9448505878d30238 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) 
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 061c46b236be0470d5f3818dc7a59b00709e404c..a36686196bb6166454cc863758e702ab05ac4fe9 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) -unsafe
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 16a26f2c55db1e21bbb3c17affae841887e4c8d8..36a3de971bd933879a05d8aed0bb6e52e3262dca 100644 (file)
@@ -14,8 +14,6 @@ SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
 LIB_REFS = System System.Xml System.Xml.Linq
 LIB_MCS_FLAGS = $(SIGN_FLAGS)
 
-PLATFORM_DEBUG_FLAGS =
-
 NO_TEST = yes
 
 include $(MCS_BUILD_DIR)/library.make
index 8a525e19ab2627e5416715a932fc6e5c98998334..65b30b9e8ec3af755be515c4e2e5d8bd4c1259db 100644 (file)
@@ -25,7 +25,7 @@ System.Security.Cryptography.Hashing.Algorithms System.Security.Cryptography.RSA
 System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
 System.Xml.XPath System.Xml.XmlDocument System.Xml.Xsl.Primitives Microsoft.Win32.Registry.AccessControl System.Diagnostics.StackTrace System.Globalization.Extensions \
 System.IO.FileSystem.AccessControl System.Private.CoreLib.InteropServices System.Reflection.TypeExtensions \
-System.Security.SecureString System.Threading.AccessControl System.Threading.Overlapped System.Xml.XPath.XDocument System.IO.Compression \
+System.Security.SecureString System.Threading.AccessControl System.Threading.Overlapped System.Xml.XPath.XDocument \
 System.Security.Cryptography.Algorithms System.Security.Cryptography.Primitives System.Text.Encoding.CodePages System.IO.FileSystem.Watcher \
 System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.IO.Pipes
 
index d92fb61f8a9b42622bb75b7adf1437104e2833da..1f20c1f89c63b6dceeb793a7241f8a2d4a6d34c2 100644 (file)
@@ -15,10 +15,13 @@ VALID_TEST_PROFILE := $(filter net_4_x, $(PROFILE))
 # The test exe is not profile specific, and compiling a 2.0 will make the 4.5 tests fail
 ifdef VALID_TEST_PROFILE
 
+TEST_HELPERS_SOURCES = \
+       ../test-helpers/NetworkHelpers.cs
+
 test-local: dtest-app.exe dtest-excfilter.exe
 
-dtest-app.exe: Test/dtest-app.cs
-       $(CSCOMPILE) -r:$(topdir)/class/lib/$(PROFILE)/System.Core.dll -r:$(topdir)/class/lib/$(PROFILE)/System.dll -out:$@ -unsafe $(PLATFORM_DEBUG_FLAGS) -optimize- Test/dtest-app.cs
+dtest-app.exe: Test/dtest-app.cs $(TEST_HELPERS_SOURCES)
+       $(CSCOMPILE) -r:$(topdir)/class/lib/$(PROFILE)/System.Core.dll -r:$(topdir)/class/lib/$(PROFILE)/System.dll -out:$@ -unsafe $(PLATFORM_DEBUG_FLAGS) -optimize- Test/dtest-app.cs $(TEST_HELPERS_SOURCES)
 
 dtest-excfilter.exe: Test/dtest-excfilter.il
        MONO_PATH=$(topdir)/class/lib/$(PROFILE) $(INTERNAL_ILASM) -out:$@ /exe /debug Test/dtest-excfilter.il
index 4b9d569b1ad941d860ff1c0f95482b1c823e2b2d..6617c146f6e138bb2e93ff51df41e1db164d1d84 100644 (file)
@@ -9,8 +9,11 @@ using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
 using System.Threading;
+using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.Sockets;
+using MonoTests.Helpers;
 
 public class TestsBase
 {
@@ -311,6 +314,10 @@ public class Tests : TestsBase, ITest2
                        wait_one ();
                        return 0;
                }
+               if (args.Length >0 && args [0] == "threadpool-io") {
+                       threadpool_io ();
+                       return 0;
+               }
                breakpoints ();
                single_stepping ();
                arguments ();
@@ -1541,6 +1548,49 @@ public class Tests : TestsBase, ITest2
        public override string virtual_method () {
                return "V2";
        }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void threadpool_bp () { }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void threadpool_io () {
+               // Start a threadpool task that blocks on I/O.
+               // Regression test for #42625
+               const int nbytes = 16;
+               var bsOut = new byte[nbytes];
+               for (int i = 0; i < nbytes; i++) {
+                       bsOut[i] = (byte)i;
+               }
+               var endPoint = NetworkHelpers.LocalEphemeralEndPoint ();
+               var l = new TcpListener (endPoint);
+               l.Start ();
+               Task<byte[]> t = Task.Run (async () => {
+                       var c = new TcpClient ();
+                       await c.ConnectAsync (endPoint.Address, endPoint.Port);
+                       var streamIn = c.GetStream ();
+                       var bs = new byte[nbytes];
+                       int nread = 0;
+                       int nremain = nbytes;
+                       while (nread < nbytes) {
+                               int r = await streamIn.ReadAsync (bs, nread, nremain);
+                               nread += r;
+                               nremain -= r;
+                       }
+                       streamIn.Close ();
+                       return bs;
+                       });
+               var s = l.AcceptTcpClient ();
+               l.Stop ();
+               // write bytes in two groups so that the task blocks on the ReadAsync
+               var streamOut = s.GetStream ();
+               var nbytesFirst = nbytes / 2;
+               var nbytesRest = nbytes - nbytesFirst;
+               streamOut.Write (bsOut, 0, nbytesFirst);
+               threadpool_bp ();
+               streamOut.Write (bsOut, nbytesFirst, nbytesRest);
+               streamOut.Close ();
+               var bsIn = t.Result;
+       }
 }
 
 class TypeLoadClass {
index c0af12cb38ac15d9f023d11cfffa62408e2fb559..88ed411da35bcabcf36968da7de70dcaa9fc7d16 100644 (file)
@@ -4035,6 +4035,22 @@ public class DebuggerTests
                // Make sure we are still in the cctor
                Assert.AreEqual (".cctor", e.Thread.GetFrames ()[0].Location.Method.Name);
        }
+
+       [Test]
+       public void ThreadpoolIOsinglestep () {
+               TearDown ();
+               Start ("dtest-app.exe", "threadpool-io");
+               // This is a regression test for #42625.  It tests the
+               // interaction (particularly in coop GC) of the
+               // threadpool I/O mechanism and the soft debugger.
+               Event e = run_until ("threadpool_io");
+               // run until we sent the task half the bytes it
+               // expects, so that it blocks waiting for the rest.
+               e = run_until ("threadpool_bp");
+               var req = create_step (e);
+               e = step_out (); // leave threadpool_bp
+               e = step_out (); // leave threadpool_io
+       }
 }
 
 }
index 955ebd0b11f9e9c0796801efc689b1fc9a88f59e..52fe6804103b0bfccf55b764a49826f570db4a1a 100644 (file)
@@ -1,2 +1,3 @@
 #include monodroid_Mono.Security_test.dll.build-failure-exclude.sources
-#include monodroid_Mono.Data.Sqlite_test.dll.new-exclude.sources
+#include monodroid_Mono.Security_test.dll.new-exclude.sources
+
index d0b2de6542978b53e0914d753b927fddb64a709d..6fa67a901d58dc20d88736050363c29295368765 100644 (file)
@@ -6,170 +6,184 @@ using Mono.Tasklets;
 namespace MonoTests.System
 {
     [TestFixture]
-       public class ContinuationsTest {
-
-               private Continuation _contA = new Continuation();
-
-               private int total = 0;
-
-               [Test]
-               public void TestContinuationsLoop() {
-                       _contA.Mark();
-                       int value = 0;
-                       int ret = _contA.Store(0);
-                       for(int i = ret; i < 10; i++) {
-                               value += i;
-                       }
-
-                       if(value > 0) {
-                               total += value;
-                               _contA.Restore(ret + 1);
-                       }
-
-                       Assert.AreEqual(total,330);
-               }
-
-               private int yields = 0;
-
-               [Test]
-               public void Yielding() {
-                       Continuation baseCont = new Continuation();
-                       Continuation taskCont = new Continuation();
-                       
-                       baseCont.Mark();
-                       taskCont.Mark();
-                       
-                       // Store the base continuation to start the task
-                       if (baseCont.Store(0) == 0) {
-                               bool done = false;
-                               int count = 0;
-
-                               while (!done) {
-                                       // Do stuff for the task.
-                                       ++count;
-                                       
-                                       // This task is counting to 100.
-                                       if (count == 100) {
-                                               done = true;
-                                       }
-
-                                       // Yield every 10 loops
-                                       else if (count % 10 == 0) {
-
-                                               // To yield, store the task continuation then restore
-                                               // the base continuation.
-                                               if (taskCont.Store(0) == 0) {
-                                                       baseCont.Restore(1);
-                                               }
-                                       }
-                               }
-                       }
-                       // When restored, 'Store' will return what was passed to Restore, in this case 1 so fall here.
-                       else {
-                               // Count the yields, then go back to the task.
-                               ++yields;
-                               taskCont.Restore(1);
-                       }
-
-                       Assert.AreEqual(9, yields);
-               }
-
-
-               public class MicroThread {
-                       
-                       public void Yield() {
-                               if (MyThread.Store(0) == 0) {
-                                       MainThread.Restore(1);
-                               }
-                       }
-
-                       public void Resume() {
-                               if (MainThread.Store(0) == 0) {
-                                       MyThread.Restore(1);
-                               }
-                       }
-
-                       public void DoWork(Action action) {
-                               if (MainThread.Store(0) == 0) {
-                                       action();
-                                       Done = true;
-                                       MainThread.Restore(1);
-                               }
-                       }
-
-                       public bool Done = false;
-                       public Continuation MainThread = new Continuation();
-                       public Continuation MyThread = new Continuation();
-               }
-               
-               public class MicroBJob {
-                       private int _Count = 0;
-                       public int Count { 
-                               get { return _Count; }
-                               set { _Count = value;}
-                       }
-
-                       public MicroThread MicroThread;
-                       public void Work() {
-                               while (Count < 100) {
-                                       ++Count;
-                                       if (Count % 10 == 0) {
-                                               MicroThread.Yield();
-                                       }
-                               }
-                       }
-               }
-
-               [Test]
-               public void MicroThreadTest() {
-                       MicroThread microA = new MicroThread();
-                       MicroThread microB = new MicroThread();
-
-                       microA.MainThread.Mark();
-                       microA.MyThread.Mark();
-                       microB.MainThread.Mark();
-                       microB.MyThread.Mark();
-
-                       Assert.AreEqual(false,microA.Done);
-                       Assert.AreEqual(false,microB.Done);
-                       
-                       microA.DoWork( () => {
-                               int count = 0;
-                               while (count < 100) {
-                                       ++count;
-                                       if (count % 10 == 0) {
-                                               microA.Yield();
-                                       }
-                               }
-                       });
-               
-                       MicroBJob jobB = new MicroBJob();
-                       jobB.MicroThread = microB;
-
-                       microB.DoWork(jobB.Work);
-
-                       Assert.AreEqual(false,microA.Done);
-                       Assert.AreEqual(false,microB.Done);
-
-                       int yields = 0;
-                       while (yields < 20) {
-                               if (!microA.Done) microA.Resume();
-                               if (!microB.Done) microB.Resume();
-                               if (microA.Done && microB.Done) break;
-                               ++yields;
-                       }
-
-                       Assert.AreEqual(true,microA.Done);
-                       Assert.AreEqual(true,microB.Done);
-                       Assert.AreEqual(100,jobB.Count);
-                       Assert.AreEqual(9,yields);
-               }
-       }
+    public class ContinuationsTest
+    {
+        [TestFixtureSetUp]
+        public void FixtureSetUp ()
+        {
+            try {
+                var temp = new Continuation ();
+            } catch (NotImplementedException) {
+                Assert.Ignore ("This platform doesn't support Tasklets.");
+            }
+        }
+
+        int total = 0;
+
+        [Test]
+        public void TestContinuationsLoop()
+        {
+            Continuation _contA = new Continuation();
+
+            _contA.Mark();
+            int value = 0;
+            int ret = _contA.Store(0);
+            for (int i = ret; i < 10; i++) {
+                value += i;
+            }
+
+            if (value > 0) {
+                total += value;
+                _contA.Restore(ret + 1);
+            }
+
+            Assert.AreEqual(total, 330);
+        }
+
+        private int yields = 0;
+
+        [Test]
+        public void Yielding()
+        {
+            Continuation baseCont = new Continuation();
+            Continuation taskCont = new Continuation();
+
+            baseCont.Mark();
+            taskCont.Mark();
+
+            // Store the base continuation to start the task
+            if (baseCont.Store(0) == 0) {
+                bool done = false;
+                int count = 0;
+
+                while (!done) {
+                    // Do stuff for the task.
+                    ++count;
+
+                    // This task is counting to 100.
+                    if (count == 100) {
+                        done = true;
+                    }
+
+                    // Yield every 10 loops
+                    else if (count % 10 == 0) {
+
+                        // To yield, store the task continuation then restore
+                        // the base continuation.
+                        if (taskCont.Store(0) == 0) {
+                            baseCont.Restore(1);
+                        }
+                    }
+                }
+            }
+            // When restored, 'Store' will return what was passed to Restore, in this case 1 so fall here.
+            else {
+                // Count the yields, then go back to the task.
+                ++yields;
+                taskCont.Restore(1);
+            }
+
+            Assert.AreEqual(9, yields);
+        }
+
+
+        public class MicroThread
+        {
+
+            public void Yield()
+            {
+                if (MyThread.Store(0) == 0) {
+                    MainThread.Restore(1);
+                }
+            }
+
+            public void Resume()
+            {
+                if (MainThread.Store(0) == 0) {
+                    MyThread.Restore(1);
+                }
+            }
+
+            public void DoWork(Action action)
+            {
+                if (MainThread.Store(0) == 0) {
+                    action();
+                    Done = true;
+                    MainThread.Restore(1);
+                }
+            }
+
+            public bool Done = false;
+            public Continuation MainThread = new Continuation();
+            public Continuation MyThread = new Continuation();
+        }
+
+        public class MicroBJob
+        {
+            private int _Count = 0;
+            public int Count
+            {
+                get { return _Count; }
+                set { _Count = value; }
+            }
+
+            public MicroThread MicroThread;
+            public void Work()
+            {
+                while (Count < 100) {
+                    ++Count;
+                    if (Count % 10 == 0) {
+                        MicroThread.Yield();
+                    }
+                }
+            }
+        }
+
+        [Test]
+        public void MicroThreadTest()
+        {
+            MicroThread microA = new MicroThread();
+            MicroThread microB = new MicroThread();
+
+            microA.MainThread.Mark();
+            microA.MyThread.Mark();
+            microB.MainThread.Mark();
+            microB.MyThread.Mark();
+
+            Assert.AreEqual(false, microA.Done);
+            Assert.AreEqual(false, microB.Done);
+
+            microA.DoWork(() =>
+            {
+                int count = 0;
+                while (count < 100) {
+                    ++count;
+                    if (count % 10 == 0) {
+                        microA.Yield();
+                    }
+                }
+            });
+
+            MicroBJob jobB = new MicroBJob();
+            jobB.MicroThread = microB;
+
+            microB.DoWork(jobB.Work);
+
+            Assert.AreEqual(false, microA.Done);
+            Assert.AreEqual(false, microB.Done);
+
+            int yields = 0;
+            while (yields < 20) {
+                if (!microA.Done) microA.Resume();
+                if (!microB.Done) microB.Resume();
+                if (microA.Done && microB.Done) break;
+                ++yields;
+            }
+
+            Assert.AreEqual(true, microA.Done);
+            Assert.AreEqual(true, microB.Done);
+            Assert.AreEqual(100, jobB.Count);
+            Assert.AreEqual(9, yields);
+        }
+    }
 }
-
-// vim: noexpandtab
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// indent-tabs-mode: t
-// End:
index 4489cceea185442afc7b62e8476f80ee2436ab13..30969ddee01b4bd65e7f9bf96225cc8369779b8e 100644 (file)
@@ -1,4 +1,5 @@
 ../../build/common/SR.cs
+../../build/common/MonoTODOAttribute.cs
 
 Assembly/AssemblyInfo.cs
 System/Util.cs
index 04a93d20c2dfb28f6caf3366b63edf152ecf6de8..0362d94774ad4b90d592729c79112b48e5b4b8d3 100644 (file)
@@ -33,131 +33,135 @@ using System.Data.SqlTypes;
 
 namespace Microsoft.SqlServer.Server 
 {
-       public sealed class SqlDataRecord : IDataRecord
+       public class SqlDataRecord : IDataRecord
        {
-               public bool GetBoolean (int ordinal)
+               public SqlDataRecord (params SqlMetaData[] metaData)
+               {
+               }
+
+               public virtual bool GetBoolean (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public byte GetByte (int ordinal)
+               public virtual byte GetByte (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public long GetBytes (int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length)
+               public virtual long GetBytes (int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length)
                {
                        throw new NotImplementedException ();
                }
 
-               public char GetChar (int ordinal)
+               public virtual char GetChar (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public long GetChars (int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length)
+               public virtual long GetChars (int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length)
                {
                        throw new NotImplementedException ();
                }
 
-               public IDataReader GetData (int ordinal)
+               public virtual IDataReader GetData (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public string GetDataTypeName (int ordinal)
+               public virtual string GetDataTypeName (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public DateTime GetDateTime (int ordinal)
+               public virtual DateTime GetDateTime (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public decimal GetDecimal (int ordinal)
+               public virtual decimal GetDecimal (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public double GetDouble (int ordinal)
+               public virtual double GetDouble (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public System.Type GetFieldType (int ordinal)
+               public virtual System.Type GetFieldType (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public float GetFloat (int ordinal)
+               public virtual float GetFloat (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public Guid GetGuid (int ordinal)
+               public virtual Guid GetGuid (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public short GetInt16 (int ordinal)
+               public virtual short GetInt16 (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public int GetInt32 (int ordinal)
+               public virtual int GetInt32 (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public long GetInt64 (int ordinal)
+               public virtual long GetInt64 (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public string GetName (int ordinal)
+               public virtual string GetName (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public int GetOrdinal (string name)
+               public virtual int GetOrdinal (string name)
                {
                        throw new NotImplementedException ();
                }
 
-               public string GetString (int ordinal)
+               public virtual string GetString (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public object GetValue (int ordinal)
+               public virtual object GetValue (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public int GetValues (object[] values)
+               public virtual int GetValues (object[] values)
                {
                        throw new NotImplementedException ();
                }
 
-               public bool IsDBNull (int ordinal)
+               public virtual bool IsDBNull (int ordinal)
                {
                        throw new NotImplementedException ();
                }
 
-               public int FieldCount {
+               public virtual int FieldCount {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public object this [string name] {
+               public virtual object this [string name] {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public object this [int ordinal] {
+               public virtual object this [int ordinal] {
                        get {
                                throw new NotImplementedException ();
                        }
index aa678a036e6d2f8219e3d89a55695dba90dfdffa..f1af864e214943a61321e2cf20cf93ff4a215cc7 100644 (file)
@@ -321,6 +321,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Proxy_Disabled ()
                {
                        var pp = WebRequest.DefaultWebProxy;
@@ -397,6 +398,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_Default ()
                {
                        bool? failed = null;
@@ -441,6 +443,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_Version_1_0 ()
                {
                        bool? failed = null;
@@ -488,6 +491,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_ClientHandlerSettings ()
                {
                        bool? failed = null;
@@ -552,6 +556,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_CustomHeaders ()
                {
                        bool? failed = null;
@@ -616,6 +621,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_CustomHeaders_SpecialSeparators ()
                {
                        bool? failed = null;
@@ -650,6 +656,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_CustomHeaders_Host ()
                {
                        bool? failed = null;
@@ -683,6 +690,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Transfer_Encoding_Chunked ()
                {
                        bool? failed = null;
@@ -712,6 +720,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Transfer_Encoding_Custom ()
                {
                        bool? failed = null;
@@ -740,6 +749,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_Content ()
                {
                        var listener = CreateListener (l => {
@@ -767,6 +777,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_Content_MaxResponseContentBufferSize ()
                {
                        var listener = CreateListener (l => {
@@ -789,6 +800,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
                {
                        var listener = CreateListener (l => {
@@ -815,6 +827,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_NoContent ()
                {
                        foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) {
@@ -847,6 +860,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Complete_Error ()
                {
                        var listener = CreateListener (l => {
@@ -867,6 +881,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Content_Get ()
                {
                        var listener = CreateListener (l => {
@@ -886,6 +901,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Content_BomEncoding ()
                {
                        var listener = CreateListener (l => {
@@ -910,6 +926,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Content_Put ()
                {
                        bool passed = false;
@@ -935,6 +952,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Send_Content_Put_CustomStream ()
                {
                        bool passed = false;
@@ -1037,6 +1055,7 @@ namespace MonoTests.System.Net.Http
 
                [Test]
                [Category ("MobileNotWorking")] // Missing encoding
+               [Category ("RequiresBSDSockets")]
                public void GetString_Many ()
                {
                        Action<HttpListenerContext> context = (HttpListenerContext l) => {
@@ -1066,6 +1085,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void GetByteArray_ServerError ()
                {
                        var listener = CreateListener (l => {
@@ -1088,6 +1108,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void DisallowAutoRedirect ()
                {
                        var listener = CreateListener (l => {
@@ -1116,6 +1137,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void RequestUriAfterRedirect ()
                {
                        var listener = CreateListener (l => {
@@ -1156,6 +1178,7 @@ namespace MonoTests.System.Net.Http
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                /*
                 * Properties may only be modified before sending the first request.
                 */
index 14f7d1a586d2c3520881ab576cda88b3cb97e37b..e900c22bfeaab4f99b6b5b94728eb66d166b1a8a 100644 (file)
@@ -136,13 +136,25 @@ namespace Mono.Net.Security
                        bool result;
 
 #if MONODROID
-                       result = AndroidPlatform.TrustEvaluateSsl (certs);
-                       if (result) {
-                               // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
-                               // Android (there are no mozroots or preinstalled root certificates),
-                               // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
-                               // Android just verified the chain; clear RemoteCertificateChainErrors.
-                               errors  &= ~SslPolicyErrors.RemoteCertificateChainErrors;
+                       try {
+                               result = AndroidPlatform.TrustEvaluateSsl (certs);
+                               if (result) {
+                                       // FIXME: check whether this is still correct.
+                                       //
+                                       // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
+                                       // Android (there are no mozroots or preinstalled root certificates),
+                                       // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
+                                       // Android just verified the chain; clear RemoteCertificateChainErrors.
+                                       errors  &= ~SslPolicyErrors.RemoteCertificateChainErrors;
+                               } else {
+                                       errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+                                       status11 = unchecked((int)0x800B010B);
+                               }
+                       } catch {
+                               result = false;
+                               errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+                               status11 = unchecked((int)0x800B010B);
+                               // Ignore
                        }
 #else
                        if (is_macosx) {
index f9183a51ef75135948c47ab0e234cf338e58fb62..7a29e8f83e3241b6d242f88239a5ca806f30fa87 100644 (file)
@@ -58,7 +58,6 @@ namespace System.Diagnostics
                        InnerList.AddRange (processModules);
                }
                
-#if !NET_2_1           
                public ProcessModule this[int index] {
                        get {
                                return (ProcessModule)InnerList[index];
@@ -79,6 +78,5 @@ namespace System.Diagnostics
                {
                        return InnerList.IndexOf (module);
                }
-#endif
        }
 }
index 19cd965cd20ba055b565ad88c241cfafa3af1719..ffa9b9899dd399ce9bed25c34e97f77166edbb13 100644 (file)
@@ -69,7 +69,6 @@ namespace System.Diagnostics
                        InnerList.AddRange (processThreads);
                }
 
-#if !NET_2_1           
                public ProcessThread this[int index] {
                        get {
                                return (ProcessThread)InnerList[index];
@@ -105,6 +104,5 @@ namespace System.Diagnostics
                {
                        InnerList.Remove (thread);
                }
-#endif
        }
 }
index 8fa752a4476c8981af260df18a15091fbe5bef54..909beb4988c8873dc7a6cd85d2b383443f1b290a 100644 (file)
@@ -16,6 +16,7 @@ using System.Threading;
 namespace MonoTests.System.Net.Mail
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class SmtpClientTest
        {
                SmtpClient smtp;
index 68118776fbefcff773d1c199d356a57b86f6c5b1..e5c70feab2c16b07d69d2a241697eea1f0d06220 100644 (file)
@@ -45,6 +45,7 @@ namespace MonoTests.System.Net.Security
 {
 
 [TestFixture]
+[Category ("RequiresBSDSockets")]
 public class SslStreamTest {
 
        byte[] m_serverCertRaw = { 48, 130, 5, 165, 2, 1, 3, 48, 130, 5, 95, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 160, 130, 5, 80, 4, 130, 5, 76, 48, 130, 5, 72, 48, 130, 2, 87, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 6, 160, 130, 2, 72, 48, 130, 2, 68, 2, 1, 0, 48, 130, 2, 61, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 48, 28, 6, 10, 42, 134, 72, 134, 247, 13, 1, 12, 1, 3, 48, 14, 4, 8, 211, 176, 234, 3, 252, 26, 32, 15, 2, 2, 7, 208, 128, 130, 2, 16, 183, 149, 35, 180, 127, 95, 163, 122, 138, 244, 29, 177, 220, 173, 46, 73, 208, 217, 211, 190, 164, 183, 21, 110, 33, 122, 98, 163, 251, 16, 23, 106, 154, 14, 52, 177, 3, 12, 248, 226, 48, 123, 211, 6, 216, 6, 192, 175, 203, 142, 141, 143, 252, 178, 7, 162, 81, 232, 159, 42, 56, 177, 191, 53, 7, 146, 189, 236, 75, 140, 210, 143, 11, 103, 64, 58, 10, 73, 123, 39, 97, 119, 166, 114, 123, 65, 68, 214, 42, 17, 156, 122, 8, 58, 184, 134, 255, 48, 64, 20, 229, 247, 196, 12, 130, 56, 176, 69, 179, 254, 216, 45, 25, 244, 240, 116, 88, 137, 66, 13, 18, 202, 199, 59, 200, 245, 19, 175, 232, 217, 211, 12, 191, 222, 26, 162, 253, 73, 201, 48, 61, 3, 248, 117, 16, 71, 233, 183, 90, 110, 91, 116, 56, 133, 223, 148, 19, 78, 140, 123, 159, 203, 78, 15, 172, 39, 190, 39, 71, 180, 155, 48, 156, 116, 212, 52, 1, 231, 201, 196, 73, 87, 68, 104, 208, 40, 104, 32, 218, 235, 245, 84, 136, 168, 51, 9, 93, 126, 46, 80, 180, 240, 144, 79, 88, 87, 159, 24, 108, 186, 9, 20, 48, 100, 148, 250, 4, 163, 115, 131, 44, 13, 38, 222, 117, 196, 196, 128, 114, 149, 97, 93, 37, 191, 3, 192, 231, 88, 80, 218, 147, 8, 192, 165, 27, 206, 56, 42, 157, 230, 223, 130, 253, 169, 182, 245, 192, 181, 18, 212, 133, 168, 73, 92, 66, 197, 117, 245, 107, 127, 23, 146, 249, 41, 66, 219, 210, 207, 221, 205, 205, 15, 110, 92, 12, 207, 76, 239, 4, 13, 129, 127, 170, 205, 253, 148, 208, 24, 129, 24, 210, 220, 85, 45, 179, 137, 66, 134, 142, 22, 112, 48, 160, 236, 232, 38, 83, 101, 55, 51, 18, 110, 99, 69, 41, 173, 107, 233, 11, 199, 23, 61, 135, 222, 94, 74, 29, 219, 80, 128, 167, 186, 254, 235, 42, 96, 134, 5, 13, 90, 59, 231, 137, 195, 207, 28, 165, 12, 218, 5, 72, 102, 61, 135, 198, 73, 250, 97, 89, 214, 179, 244, 194, 23, 142, 157, 4, 243, 90, 69, 54, 10, 139, 76, 95, 40, 225, 219, 59, 15, 54, 182, 206, 142, 228, 248, 79, 156, 129, 246, 63, 6, 6, 236, 44, 67, 116, 213, 170, 47, 193, 186, 139, 25, 80, 166, 57, 99, 231, 156, 191, 117, 65, 76, 7, 243, 244, 127, 225, 210, 190, 164, 141, 46, 36, 99, 111, 203, 133, 127, 80, 28, 61, 160, 36, 132, 182, 16, 41, 39, 185, 232, 123, 32, 57, 189, 100, 152, 38, 205, 5, 189, 240, 65, 3, 191, 73, 85, 12, 209, 180, 1, 194, 70, 124, 57, 71, 48, 230, 235, 122, 175, 157, 35, 233, 83, 40, 20, 169, 224, 14, 11, 216, 48, 194, 105, 25, 187, 210, 182, 6, 184, 73, 95, 85, 210, 227, 113, 58, 10, 186, 175, 254, 25, 102, 39, 3, 2, 200, 194, 197, 200, 224, 77, 164, 8, 36, 114, 48, 130, 2, 233, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 160, 130, 2, 218, 4, 130, 2, 214, 48, 130, 2, 210, 48, 130, 2, 206, 6, 11, 42, 134, 72, 134, 247, 13, 1, 12, 10, 1, 2, 160, 130, 2, 166, 48, 130, 2, 162, 48, 28, 6, 10, 42, 134, 72, 134, 247, 13, 1, 12, 1, 3, 48, 14, 4, 8, 178, 13, 52, 135, 85, 49, 79, 105, 2, 2, 7, 208, 4, 130, 2, 128, 21, 84, 227, 109, 230, 144, 140, 170, 117, 250, 179, 207, 129, 100, 126, 126, 29, 231, 94, 140, 45, 26, 168, 45, 240, 4, 170, 73, 98, 115, 109, 96, 177, 206, 6, 80, 170, 22, 237, 144, 58, 95, 59, 26, 85, 135, 178, 69, 184, 44, 122, 81, 213, 135, 149, 198, 246, 83, 68, 129, 2, 186, 118, 33, 44, 214, 227, 240, 220, 51, 175, 220, 220, 180, 113, 216, 101, 138, 81, 54, 38, 0, 216, 30, 29, 187, 213, 230, 12, 181, 130, 21, 241, 98, 120, 41, 150, 176, 69, 37, 169, 249, 123, 212, 254, 135, 154, 214, 127, 39, 105, 149, 180, 218, 41, 207, 75, 70, 105, 169, 185, 169, 132, 173, 188, 82, 251, 71, 234, 136, 5, 254, 110, 223, 34, 4, 145, 7, 19, 51, 123, 140, 75, 226, 0, 21, 220, 228, 223, 218, 8, 169, 210, 194, 139, 93, 218, 55, 40, 174, 50, 238, 38, 166, 222, 103, 0, 209, 88, 131, 51, 222, 154, 217, 18, 172, 73, 17, 133, 54, 173, 208, 118, 104, 167, 113, 153, 223, 251, 154, 120, 176, 18, 127, 51, 206, 164, 77, 86, 9, 82, 212, 86, 162, 206, 230, 79, 217, 178, 42, 217, 162, 152, 188, 217, 59, 212, 117, 200, 135, 75, 74, 43, 1, 42, 79, 180, 164, 250, 122, 103, 103, 157, 11, 14, 33, 48, 8, 108, 155, 46, 124, 223, 204, 169, 124, 104, 11, 246, 213, 226, 16, 125, 17, 228, 15, 178, 141, 79, 78, 115, 76, 131, 122, 166, 124, 154, 1, 174, 178, 176, 213, 208, 188, 71, 118, 220, 168, 64, 218, 176, 134, 38, 229, 14, 109, 162, 125, 16, 57, 249, 201, 180, 17, 182, 143, 184, 12, 248, 113, 65, 70, 109, 79, 249, 34, 170, 35, 228, 219, 121, 202, 228, 121, 127, 255, 22, 173, 202, 171, 33, 232, 4, 240, 142, 216, 80, 56, 177, 83, 93, 123, 217, 213, 157, 99, 34, 194, 61, 228, 239, 194, 20, 27, 9, 53, 132, 79, 19, 97, 107, 31, 51, 39, 176, 223, 90, 88, 67, 138, 194, 169, 176, 144, 202, 119, 146, 74, 27, 118, 63, 129, 230, 101, 104, 75, 116, 49, 223, 254, 225, 70, 206, 183, 11, 134, 148, 10, 55, 57, 50, 178, 144, 164, 139, 233, 169, 109, 186, 211, 95, 123, 75, 111, 192, 187, 127, 240, 45, 226, 194, 240, 128, 10, 79, 178, 192, 66, 21, 197, 24, 171, 141, 255, 185, 230, 84, 206, 151, 9, 93, 115, 162, 12, 115, 129, 218, 103, 219, 183, 142, 123, 3, 110, 139, 208, 4, 146, 76, 99, 246, 240, 32, 169, 148, 16, 146, 172, 230, 36, 56, 145, 23, 94, 209, 92, 38, 244, 127, 70, 121, 253, 66, 55, 36, 140, 98, 105, 233, 112, 24, 23, 230, 112, 62, 244, 12, 48, 30, 51, 0, 18, 244, 139, 66, 245, 234, 203, 195, 52, 119, 255, 84, 82, 204, 100, 176, 167, 24, 224, 8, 127, 214, 148, 115, 242, 56, 190, 72, 221, 68, 252, 36, 74, 254, 57, 52, 96, 20, 173, 32, 236, 87, 15, 16, 76, 9, 48, 3, 61, 2, 137, 137, 9, 68, 213, 99, 163, 63, 201, 83, 241, 98, 7, 117, 108, 4, 123, 170, 18, 10, 19, 198, 31, 170, 15, 247, 216, 145, 172, 239, 137, 181, 80, 160, 24, 11, 35, 131, 58, 218, 22, 250, 215, 52, 160, 246, 197, 183, 92, 137, 0, 245, 63, 49, 183, 246, 195, 58, 63, 4, 75, 10, 92, 131, 181, 59, 78, 247, 44, 150, 49, 49, 107, 211, 62, 71, 62, 222, 159, 161, 118, 236, 55, 219, 49, 0, 3, 82, 236, 96, 20, 83, 39, 245, 208, 240, 245, 174, 218, 49, 21, 48, 19, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 21, 49, 6, 4, 4, 1, 0, 0, 0, 48, 61, 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20, 30, 154, 48, 126, 198, 239, 114, 62, 12, 58, 129, 172, 67, 156, 76, 214, 62, 205, 89, 28, 4, 20, 135, 177, 105, 83, 79, 93, 181, 149, 169, 49, 112, 201, 70, 212, 153, 79, 198, 163, 137, 90, 2, 2, 7, 208 };
index 9c3765e2d5b7ea95c8a4902f26075af16f0e5c76..e51f2d9b7d526e14185622f3337904180ebd89a9 100644 (file)
@@ -16,6 +16,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net.Sockets
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class NetworkStreamTest
        {
                [Test]
index 3815b623c39f53085f8670e788952f2ffcf89077..28bc6bb81745f29059c186633126c3addaabfa9a 100644 (file)
@@ -6,6 +6,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net.Sockets
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class SocketAcceptAsyncTest
        {
                [Test]
index d59d39fad89d232798a341ce06bdd238b3da044f..d286668707e437635c1bc4e3920b45b4d2fa7072 100644 (file)
@@ -8,6 +8,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net.Sockets
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class SocketAsyncTest
        {
                Socket serverSocket;
index f4586a253f8ce09c2b2178d6f5e08ad53b55445a..9551c1e6027131d4217bd59a13d986438873d5e2 100755 (executable)
@@ -28,6 +28,7 @@ using MonoTests.Helpers;
 namespace MonoTests.System.Net.Sockets
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class SocketTest
        {
                // note: also used in SocketCas tests
index 91b461487eb0cc38526671ac56a1ca34797fc8fa..4d3b8325048d9038ebfcaf8210960ebc71562f1a 100644 (file)
@@ -21,6 +21,7 @@ namespace MonoTests.System.Net.Sockets
        /// Tests System.Net.Sockets.TcpClient
        /// </summary>
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class TcpClientTest
        {
                
index b8594b8f11e7e489de6a1834bcb4dda1c1d7f655..1e211cf524920b999f0f090353814030a6dff829 100644 (file)
@@ -20,6 +20,7 @@ using MonoTests.Helpers;
 namespace MonoTests.System.Net.Sockets
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class TcpListenerTest
        {
                [Test]
index b7a537f662be204c61ffb1f6b1c9b6e0911d06cf..66b15308d1f84cb08efaae91d0bbe5b8e3acc62d 100644 (file)
@@ -15,6 +15,7 @@ using NUnit.Framework;
 
 namespace MonoTests.System.Net.Sockets {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class UdpClientTest {
                [Test] // .ctor ()
                public void Constructor1 ()
index da02abdd54747221770c7dc9692e6bf794a03c1c..37c40d7445e070cd8d5021dc238253b6bdac5db5 100644 (file)
@@ -9,6 +9,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class CookieParserTest
        {
                public const string A = "Foo=Bar, expires=World; expires=Sat, 11-Oct-14 22:45:19 GMT, A=B";
index a1b5f51cdd2ec37df3ae8037cfc242a9986c4ecb..dcc82f61678777cc202e1b94417d4b7a82c0d114 100644 (file)
@@ -19,6 +19,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net\r
 {\r
        [TestFixture]\r
+       [Category ("RequiresBSDSockets")]\r
        public class DnsTest\r
        {\r
                private String site1Name = "google-public-dns-a.google.com",\r
@@ -55,7 +56,7 @@ namespace MonoTests.System.Net
 \r
                        IAsyncResult async = Dns.BeginResolve (site1Dot, null, null);\r
                        IPHostEntry entry = Dns.EndResolve (async);\r
-                       SubTestValidIPHostEntry (entry);
+                       SubTestValidIPHostEntry (entry);\r
                        var ip = GetIPv4Address (entry);\r
                        Assert.AreEqual (site1Dot, ip.ToString ());\r
                }\r
@@ -306,7 +307,7 @@ namespace MonoTests.System.Net
                {\r
                        IPAddress addr = new IPAddress (IPAddress.NetworkToHostOrder ((int) site2IP));\r
                        IPHostEntry h = Dns.GetHostByAddress (addr);\r
-                       SubTestValidIPHostEntry (h);
+                       SubTestValidIPHostEntry (h);\r
                        var ip = GetIPv4Address (h);\r
                        Assert.AreEqual (addr.ToString (), ip.ToString ());\r
                }\r
index 6793d2a48fdeffefa3c47d532c664f915bcc4330..5f4166eecf855549bfd4ea8a51d9ffa556b14cb1 100644 (file)
@@ -25,6 +25,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class FileWebRequestTest
        {
                private string _tempDirectory;
index e740e1c67a5370f5aaf0caa2358c611a641f6336..93697cd29294145f8c1466224e44eacb5b210667 100644 (file)
@@ -19,6 +19,7 @@ using System.Threading;
 namespace MonoTests.System.Net 
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class FtpWebRequestTest
        {
                FtpWebRequest defaultRequest;
index 3afff1226ae85d5d8207c551ca5a2dac459f6cec..b0cedc555a4e8b34674790e2d6744c1a0e269b53 100644 (file)
@@ -47,6 +47,7 @@ using MonoTests.Helpers;
 namespace MonoTests.System.Net {
        
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpListener2Test {
                
                private HttpListener _listener = null;
@@ -645,6 +646,7 @@ namespace MonoTests.System.Net {
        }
 
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpListenerBugs {
                [Test]
                public void TestNonChunkedAsync ()
index 873481cbc5a44440c3343e13da21031d611f20bf..21589dc6c30914ebe227c22b04a99143a720457e 100644 (file)
@@ -57,6 +57,7 @@ namespace MonoTests.System.Net {
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void AddOne ()
                {
                        HttpListener listener = new HttpListener ();
@@ -70,6 +71,7 @@ namespace MonoTests.System.Net {
                }
 
                [Test]
+               [Category ("RequiresBSDSockets")]
                public void Duplicate ()
                {
                        HttpListener listener = new HttpListener ();
index 6ff1b33260ed2ab7e82883d4f600a12e89136888..c9227fd5b39dc09c6ce53f618c084c05d56b6b7f 100644 (file)
@@ -42,6 +42,7 @@ using MonoTests.Helpers;
 namespace MonoTests.System.Net
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpListenerRequestTest
        {
                [Test]
index f2ae436d29f8c9d2672b46f54cf960c1be3f893f..8620d1ce32a9b34bd6b98f40ea9ac0805791250a 100644 (file)
@@ -37,6 +37,7 @@ using MonoTests.Helpers;
 
 namespace MonoTests.System.Net {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpListenerTest {
 
                int port;
index ee6c82895e3e7ae5914ca2ffb463a39cc7fdb9d8..b7097b5db56a7e930149f96f641b3df8997559a1 100644 (file)
@@ -36,6 +36,7 @@ using MonoTests.Helpers;
 namespace MonoTests.System.Net
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpWebRequestTest
        {
                private Random rand = new Random ();
@@ -2762,6 +2763,7 @@ namespace MonoTests.System.Net
        }
 
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpRequestStreamTest
        {
                [Test]
index 580c548890771190f6d5c2ef14e440e8b44fd53a..10d7d807444ce7527e56c73b601788be68f08664 100644 (file)
@@ -21,6 +21,7 @@ using NUnit.Framework;
 namespace MonoTests.System.Net
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpWebResponseTest
        {
                [Test]
@@ -476,6 +477,7 @@ namespace MonoTests.System.Net
        }
 
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class HttpResponseStreamTest
        {
                [Test]
index b671e9e92358dec824ecbdf2a6f615640cfd056e..9eb5877052ea3430303a703c1219ad5f73f81d1e 100644 (file)
@@ -21,6 +21,7 @@ using MonoTests.Helpers;
 namespace MonoTests.System.Net
 {
        [TestFixture]
+       [Category ("RequiresBSDSockets")]
        public class WebClientTest
        {
                private string _tempFolder;
index a3ddb3af8438429c7edd7c0809135dd4a0ba0402..34ce1a370a1d4ed737bfe721ce2d4e03104c27b0 100644 (file)
@@ -414,6 +414,7 @@ namespace MonoTests.System.Net {
        }\r
 
        [Test] // Covers #41477
+       [Category ("RequiresBSDSockets")]
        public void TestReceiveCancelation ()
        {
                var uri = "http://localhost:" + NetworkHelpers.FindFreePort () + "/";
index 88eeeee8f0c75c53ecada2173314e374ac1d5416..68db33f3944ceb3dc511a2966c1674244a3a3725 100644 (file)
@@ -262,11 +262,11 @@ namespace Mono {
                }
 
                [MethodImpl(MethodImplOptions.InternalCall)]
-               unsafe extern static void GPtrArrayFree (RuntimeStructs.GPtrArray* value, bool freeSeg);
+               unsafe extern static void GPtrArrayFree (RuntimeStructs.GPtrArray* value);
 
-               internal static void DestroyAndFree (ref RuntimeGPtrArrayHandle h, bool freeSeg) {
+               internal static void DestroyAndFree (ref RuntimeGPtrArrayHandle h) {
                        unsafe {
-                               GPtrArrayFree (h.value, freeSeg);
+                               GPtrArrayFree (h.value);
                                h.value = null;
                        }
                }
diff --git a/mcs/class/corlib/Mono/RuntimeMarshal.cs b/mcs/class/corlib/Mono/RuntimeMarshal.cs
new file mode 100644 (file)
index 0000000..38da4e2
--- /dev/null
@@ -0,0 +1,65 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+namespace Mono {
+       internal static class RuntimeMarshal {
+               internal static string PtrToUtf8String (IntPtr ptr)
+               {
+                       unsafe {
+                               return new String ((sbyte*)ptr);
+                       }
+               }
+
+               internal static SafeStringMarshal MarshalString (string str)
+               {
+                       return new SafeStringMarshal (str);
+               }
+
+               static int DecodeBlobSize (IntPtr in_ptr, out IntPtr out_ptr)
+               {
+                       uint size;
+                       unsafe {
+                               byte *ptr = (byte*)in_ptr;
+       
+                               if ((*ptr & 0x80) == 0) {
+                                       size = (uint)(ptr [0] & 0x7f);
+                                       ptr++;
+                               } else if ((*ptr & 0x40) == 0){
+                                       size = (uint)(((ptr [0] & 0x3f) << 8) + ptr [1]);
+                                       ptr += 2;
+                               } else {
+                                       size = (uint)(((ptr [0] & 0x1f) << 24) +
+                                               (ptr [1] << 16) +
+                                               (ptr [2] << 8) +
+                                               ptr [3]);
+                                       ptr += 4;
+                               }
+                               out_ptr = (IntPtr)ptr;
+                       }
+
+                       return (int)size;
+               }
+
+               internal static byte[] DecodeBlobArray (IntPtr ptr)
+               {
+                       IntPtr out_ptr;
+                       int size = DecodeBlobSize (ptr, out out_ptr);
+                       byte[] res = new byte [size];
+                       Marshal.Copy (out_ptr, res, 0, size);
+                       return res;
+               }
+
+               internal static int AsciHexDigitValue (int c)
+               {
+                       if (c >= '0' && c <= '9')
+                               return c - '0';
+                       if (c >= 'a' && c <= 'f')
+                               return c - 'a' + 10;
+                       return c - 'A' + 10;
+               }
+
+               [MethodImpl (MethodImplOptions.InternalCall)]
+               internal static extern void FreeAssemblyName (ref MonoAssemblyName name);
+       }
+}
index 20cd93fdaecfa0c70be0f1ae84d492588b1b41aa..ae4550632088f8f90a6bb408a699180857c097b5 100644 (file)
@@ -45,5 +45,20 @@ namespace Mono {
                }
        }
 
+       //Maps to metadata-internals.h:: MonoAssemblyName
+       internal unsafe struct MonoAssemblyName
+       {
+               const int MONO_PUBLIC_KEY_TOKEN_LENGTH = 17;
+
+               internal IntPtr name;
+               internal IntPtr culture;
+               internal IntPtr hash_value;
+               internal IntPtr public_key;
+               internal fixed byte public_key_token [MONO_PUBLIC_KEY_TOKEN_LENGTH];
+               internal uint hash_alg;
+               internal uint hash_len;
+               internal uint flags;
+               internal ushort major, minor, build, revision;
+               internal ushort arch;
+       }
 }
-       
index 6332259b9a1781d82862d26130c5de0e499a5124..0441c9b8bd8b9dcbafdf7cd95c222c97558d32b3 100644 (file)
@@ -13,29 +13,16 @@ using System;
 using System.Runtime.CompilerServices;
 
 namespace Mono {
-       internal sealed class SafeGPtrArrayHandle : IDisposable {
+       internal struct SafeGPtrArrayHandle : IDisposable {
                RuntimeGPtrArrayHandle handle;
-               bool freeSeg;
 
-               internal SafeGPtrArrayHandle (IntPtr ptr, bool freeSeg)
+               internal SafeGPtrArrayHandle (IntPtr ptr)
                {
                        handle = new RuntimeGPtrArrayHandle (ptr);
-                       this.freeSeg = freeSeg;
-               }
-
-               ~SafeGPtrArrayHandle ()
-               {
-                       Dispose (false);
-               }
-
-               void Dispose (bool disposing)
-               {
-                       RuntimeGPtrArrayHandle.DestroyAndFree (ref handle, freeSeg);
                }
 
                public void Dispose () {
-                       Dispose (true);
-                       GC.SuppressFinalize (this);
+                       RuntimeGPtrArrayHandle.DestroyAndFree (ref handle);
                }
 
                internal int Length {
diff --git a/mcs/class/corlib/Mono/SafeStringMarshal.cs b/mcs/class/corlib/Mono/SafeStringMarshal.cs
new file mode 100644 (file)
index 0000000..c18f0d3
--- /dev/null
@@ -0,0 +1,46 @@
+//
+// Safe wrapper for a string and its UTF8 encoding
+//
+// Authors:
+//   Aleksey Kliger <aleksey@xamarin.com>
+//   Rodrigo Kumpera <kumpera@xamarin.com>
+//
+// Copyright 2016 Dot net foundation.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Mono  {
+       internal struct SafeStringMarshal : IDisposable {
+               readonly string str;
+               IntPtr marshaled_string;
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public extern static IntPtr StringToUtf8 (string str);
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public extern static void GFree (IntPtr ptr);
+
+               public SafeStringMarshal (string str) {
+                       this.str = str;
+                       this.marshaled_string = IntPtr.Zero;
+               }
+
+               public IntPtr Value {
+                       get {
+                               if (marshaled_string == IntPtr.Zero && str != null)
+                                       marshaled_string = StringToUtf8 (str);
+                               return marshaled_string;
+                       }
+               }
+
+               public void Dispose () {
+                       if (marshaled_string != IntPtr.Zero) {
+                               GFree (marshaled_string);
+                               marshaled_string = IntPtr.Zero;
+                       }
+               }
+       }
+}
index 08159216f565de940787de6b3441daf5875ce092..8a49451936e5fd80e95e17913a2a3025084c5f7d 100644 (file)
@@ -472,12 +472,13 @@ namespace System
                static extern Type MakeGenericType (Type gt, Type [] types);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal extern IntPtr GetMethodsByName_native (string name, BindingFlags bindingAttr, bool ignoreCase);
+               internal extern IntPtr GetMethodsByName_native (IntPtr namePtr, BindingFlags bindingAttr, bool ignoreCase);
 
                internal RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, RuntimeType reflectedType)
                {
                        var refh = new RuntimeTypeHandle (reflectedType);
-                       using (var h = new Mono.SafeGPtrArrayHandle (GetMethodsByName_native (name, bindingAttr, ignoreCase), false)) {
+                       using (var namePtr = new Mono.SafeStringMarshal (name))
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetMethodsByName_native (namePtr.Value, bindingAttr, ignoreCase))) {
                                var n = h.Length;
                                var a = new RuntimeMethodInfo [n];
                                for (int i = 0; i < n; i++) {
@@ -489,7 +490,7 @@ namespace System
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern IntPtr GetPropertiesByName_native (string name, BindingFlags bindingAttr, bool icase);           
+               extern IntPtr GetPropertiesByName_native (IntPtr name, BindingFlags bindingAttr, bool icase);           
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern IntPtr GetConstructors_native (BindingFlags bindingAttr);
@@ -497,7 +498,7 @@ namespace System
                RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, RuntimeType reflectedType)
                {
                        var refh = new RuntimeTypeHandle (reflectedType);
-                       using (var h = new Mono.SafeGPtrArrayHandle (GetConstructors_native (bindingAttr), false)) {
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetConstructors_native (bindingAttr))) {
                                var n = h.Length;
                                var a = new RuntimeConstructorInfo [n];
                                for (int i = 0; i < n; i++) {
@@ -511,7 +512,8 @@ namespace System
                RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, RuntimeType reflectedType)
                {
                        var refh = new RuntimeTypeHandle (reflectedType);
-                       using (var h = new Mono.SafeGPtrArrayHandle (GetPropertiesByName_native (name, bindingAttr, icase), false)) {
+                       using (var namePtr = new Mono.SafeStringMarshal (name))
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetPropertiesByName_native (namePtr.Value, bindingAttr, icase))) {
                                var n = h.Length;
                                var a = new RuntimePropertyInfo [n];
                                for (int i = 0; i < n; i++) {
@@ -669,15 +671,16 @@ namespace System
                extern int GetGenericParameterPosition ();
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern IntPtr GetEvents_native (string name, BindingFlags bindingAttr);
+               extern IntPtr GetEvents_native (IntPtr name, BindingFlags bindingAttr);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern IntPtr GetFields_native (string name, BindingFlags bindingAttr);
+               extern IntPtr GetFields_native (IntPtr name, BindingFlags bindingAttr);
 
                RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, RuntimeType reflectedType)
                {
                        var refh = new RuntimeTypeHandle (reflectedType);
-                       using (var h = new Mono.SafeGPtrArrayHandle (GetFields_native (name, bindingAttr), false)) {
+                       using (var namePtr = new Mono.SafeStringMarshal (name))
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetFields_native (namePtr.Value, bindingAttr))) {
                                int n = h.Length;
                                var a = new RuntimeFieldInfo[n];
                                for (int i = 0; i < n; i++) {
@@ -691,7 +694,8 @@ namespace System
                RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, RuntimeType reflectedType)
                {
                        var refh = new RuntimeTypeHandle (reflectedType);
-                       using (var h = new Mono.SafeGPtrArrayHandle (GetEvents_native (name, bindingAttr), false)) {
+                       using (var namePtr = new Mono.SafeStringMarshal (name))
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetEvents_native (namePtr.Value, bindingAttr))) {
                                int n = h.Length;
                                var a = new RuntimeEventInfo[n];
                                for (int i = 0; i < n; i++) {
@@ -706,7 +710,24 @@ namespace System
                public extern override Type[] GetInterfaces();
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern RuntimeType[] GetNestedTypes_internal (string name, BindingFlags bindingAttr);           
+               extern IntPtr GetNestedTypes_native (IntPtr name, BindingFlags bindingAttr);
+
+               RuntimeType[] GetNestedTypes_internal (string displayName, BindingFlags bindingAttr)
+               {
+                       string internalName = null;
+                       if (displayName != null)
+                               internalName = TypeIdentifiers.FromDisplay (displayName).InternalName;
+                       using (var namePtr = new Mono.SafeStringMarshal (internalName))
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetNestedTypes_native (namePtr.Value, bindingAttr))) {
+                               int n = h.Length;
+                               var a = new RuntimeType [n];
+                               for (int i = 0; i < n; i++) {
+                                       var th = new RuntimeTypeHandle (h[i]);
+                                       a[i] = (RuntimeType) Type.GetTypeFromHandle (th);
+                               }
+                               return a;
+                       }
+               }
 
                public override string AssemblyQualifiedName {
                        get {
index c6c32095cbf9aa19e422c014d1bcf41e32e43901..92389257c5c788f84d7050c696d81075ff9109ee 100644 (file)
@@ -139,14 +139,15 @@ namespace System.IO
                                FileShare.None, bufferSize);
                }
 
-#if !NET_2_1
                [MonoLimitation ("FileOptions are ignored")]
                public static FileStream Create (string path, int bufferSize,
                                                 FileOptions options)
                {
-                       return Create (path, bufferSize, options, null);
+                       return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
+                               FileShare.None, bufferSize, options);
                }
-               
+
+#if !NET_2_1
                [MonoLimitation ("FileOptions and FileSecurity are ignored")]
                public static FileStream Create (string path, int bufferSize,
                                                 FileOptions options,
index 6a6fcd36f5abe114d6eaa3751587690b41811a6c..0a189e1faa7e70b7a2db00d32532f5ee80005c82 100644 (file)
@@ -1114,8 +1114,7 @@ namespace System.Reflection.Emit
 
                public override AssemblyName GetName (bool copiedName)
                {
-                       AssemblyName aname = new AssemblyName ();
-                       FillName (this, aname);
+                       var aname = AssemblyName.Create (this, false);
 
                        if (sn != null) {
                                aname.SetPublicKey (sn.PublicKey);
index c90059d3a87432239118d0ab5d144e5bcac1a03e..174d5da5813c72bd9f6b960af06813128db67a7d 100644 (file)
@@ -88,7 +88,7 @@ namespace System.Reflection {
 
                // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
 #pragma warning disable 649
-               private IntPtr _mono_assembly;
+               internal IntPtr _mono_assembly;
 #pragma warning restore 649
 
                private ResolveEventHolder resolve_event_holder;
@@ -425,9 +425,6 @@ namespace System.Reflection {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               static extern internal void FillName (Assembly ass, AssemblyName aname);
-
                public virtual AssemblyName GetName (Boolean copiedName)
                {
                        throw new NotImplementedException ();
index 42006c3e80f99ce9594cecccc582d21a1b0fc395..7ce7241cc98c8851f6893ca193722e3c679c5f90 100644 (file)
@@ -40,6 +40,7 @@ using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
 using System.IO;
 
+using Mono;
 using Mono.Security;
 using Mono.Security.Cryptography;
 
@@ -84,17 +85,29 @@ namespace System.Reflection {
                }
 
                [MethodImpl (MethodImplOptions.InternalCall)]
-               static extern bool ParseName (AssemblyName aname, string assemblyName);
-               
+               static extern bool ParseAssemblyName (IntPtr name, out MonoAssemblyName aname, out bool is_version_definited, out bool is_token_defined);
+
                public AssemblyName (string assemblyName)
                {
                        if (assemblyName == null)
                                throw new ArgumentNullException ("assemblyName");
                        if (assemblyName.Length < 1)
                                throw new ArgumentException ("assemblyName cannot have zero length.");
-                               
-                       if (!ParseName (this, assemblyName))
-                               throw new FileLoadException ("The assembly name is invalid.");
+
+                       using (var name = RuntimeMarshal.MarshalString (assemblyName)) {
+                               MonoAssemblyName nativeName;
+                               bool isVersionDefined, isTokenDefined;
+                               //ParseName free the name if it fails.
+                               if (!ParseAssemblyName (name.Value, out nativeName, out isVersionDefined, out isTokenDefined))
+                                       throw new FileLoadException ("The assembly name is invalid.");
+                               try {
+                                       unsafe {
+                                               this.FillName (&nativeName, null, isVersionDefined, false, isTokenDefined);
+                                       }
+                               } finally {
+                                       RuntimeMarshal.FreeAssemblyName (ref nativeName);
+                               }
+                       }
                }
                
                [MonoLimitation ("Not used, as the values are too limited;  Mono supports more")]
@@ -449,5 +462,63 @@ namespace System.Reflection {
                                contentType = value;
                        }
                }
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               static extern unsafe MonoAssemblyName* GetNativeName (IntPtr assembly_ptr);
+
+               internal unsafe void FillName (MonoAssemblyName *native, string codeBase, bool addVersion, bool addPublickey, bool defaultToken)
+               {
+                       this.name = RuntimeMarshal.PtrToUtf8String (native->name);
+
+                       this.major = native->major;
+                       this.minor = native->minor;
+                       this.build = native->build;
+                       this.revision = native->revision;
+
+                       this.flags = (AssemblyNameFlags)native->flags;
+
+                       this.hashalg = (AssemblyHashAlgorithm)native->hash_alg;
+
+                       this.versioncompat = AssemblyVersionCompatibility.SameMachine;
+                       this.processor_architecture = (ProcessorArchitecture)native->arch;
+
+                       if (addVersion)
+                               this.version = new Version (this.major, this.minor, this.build, this.revision);
+
+                       this.codebase = codeBase;
+
+                       if (native->culture != IntPtr.Zero)
+                               this.cultureinfo = CultureInfo.CreateCulture ( RuntimeMarshal.PtrToUtf8String (native->culture), false);
+
+                       if (native->public_key != IntPtr.Zero) {
+                               this.publicKey = RuntimeMarshal.DecodeBlobArray (native->public_key);
+                               this.flags |= AssemblyNameFlags.PublicKey;
+                       } else if (addPublickey) {
+                               this.publicKey = EmptyArray<byte>.Value;
+                               this.flags |= AssemblyNameFlags.PublicKey;
+                       }
+
+                       // MonoAssemblyName keeps the public key token as an hexadecimal string
+                       if (native->public_key_token [0] != 0) {
+                               byte[] keyToken = new byte [8];
+                               for (int i = 0, j = 0; i < 8; ++i) {
+                                       keyToken [i] = (byte)(RuntimeMarshal.AsciHexDigitValue (native->public_key_token [j++]) << 4);
+                                       keyToken [i] |= (byte)RuntimeMarshal.AsciHexDigitValue (native->public_key_token [j++]);
+                               }
+                               this.keyToken = keyToken;
+                       } else if (defaultToken) {
+                               this.keyToken = EmptyArray<byte>.Value;
+                       }
+               }
+
+               internal static AssemblyName Create (Assembly assembly, bool fillCodebase)
+               {
+                       AssemblyName aname = new AssemblyName ();
+                       unsafe {
+                               MonoAssemblyName *native = GetNativeName (assembly._mono_assembly);
+                               aname.FillName (native, fillCodebase ? assembly.CodeBase : null, true, true, true);
+                       }
+                       return aname;
+               }
        }
 }
index c433bc93dc8866598b839801f6ccb0effbaea6b3..a62b86a63ef2a8665c2315a5f8ae03c3c85ae092 100644 (file)
@@ -41,6 +41,8 @@ using System.Security;
 using System.Security.Policy;
 using System.Security.Permissions;
 
+using Mono;
+
 namespace System.Reflection {
 
        abstract class RuntimeAssembly : Assembly
@@ -162,12 +164,8 @@ namespace System.Reflection {
                                var _ = CodeBase; // this will ensure the Demand is made
                        }
 #endif
-
-                       AssemblyName aname = new AssemblyName ();
-                       FillName (this, aname);
-                       return aname;
+                       return AssemblyName.Create (this, true);
                }
-
        }
 
        [ComVisible (true)]
index 3507b2d46371500d8667a0920af9069da2ae9340..a55f093678f618f00cb384f8fbd809f16264a1cd 100644 (file)
@@ -66,6 +66,10 @@ namespace System.Runtime.CompilerServices
                        GC.register_ephemeron_array (data);
                }
 
+               ~ConditionalWeakTable ()
+               {
+               }
+
                /*LOCKING: _lock must be held*/
                void Rehash () {
                        uint newSize = (uint)HashHelpers.GetPrime ((data.Length << 1) | 1);
index 74bc4764adcc0f09bae453359ac832b31b46f715..74b8b65b3f17afe89deeb11ffaf5cbe1a9883452 100644 (file)
@@ -81,8 +81,10 @@ namespace System.Runtime.Remoting.Proxies
                                return field.GetValue(o);
                        }
 
-                       object[] inArgs = new object[] { Type.GetTypeFromHandle(typeHandle).FullName,
-                                                         field.Name };
+                       string typeName = Type.GetTypeFromHandle(typeHandle).FullName;
+                       string fieldName = field.Name;
+                       object[] inArgs = new object[] { typeName,
+                                                         fieldName };
                        object[] outArgsMsg = new object[1];
                        MethodInfo minfo = typeof(object).GetMethod("FieldGetter", BindingFlags.NonPublic | BindingFlags.Instance);
                        if (minfo == null)
@@ -95,6 +97,36 @@ namespace System.Runtime.Remoting.Proxies
                                throw exc;
                        return outArgs[0];
                }
+
+               internal void StoreRemoteField (IntPtr classPtr, IntPtr fieldPtr, object arg) {
+                       Mono.RuntimeClassHandle classHandle = new Mono.RuntimeClassHandle (classPtr);
+                       RuntimeFieldHandle fieldHandle = new RuntimeFieldHandle (fieldPtr);
+                       RuntimeTypeHandle typeHandle = classHandle.GetTypeHandle ();
+                       FieldInfo field = FieldInfo.GetFieldFromHandle (fieldHandle);
+
+                       if (InCurrentContext ()) {
+                               object o = _rp._server;
+                               field.SetValue (o, arg);
+                               return;
+                       }
+
+                       string typeName = Type.GetTypeFromHandle (typeHandle).FullName;
+                       string fieldName = field.Name;
+                       object [] inArgs = new object[] { typeName,
+                                                         fieldName,
+                                                         arg };
+                       MethodInfo minfo = typeof(object).GetMethod ("FieldSetter", BindingFlags.NonPublic | BindingFlags.Instance);
+                       if (minfo == null)
+                               throw new MissingMethodException ("System.Object", "FieldSetter");
+
+                       MonoMethodMessage msg = new MonoMethodMessage (minfo, inArgs, null);
+                       object [] outArgs;
+                       Exception exc;
+                       RealProxy.PrivateInvoke (_rp, msg, out exc, out outArgs);
+                       if (exc != null)
+                               throw exc;
+               }
+
        }
 #pragma warning restore 169, 649
        
index 2b031f332871e671df0acdb1e5972283ddc965b7..b6a2d92eef7f8644942936af9c06aa92437233f3 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 151;
+               private const int mono_corlib_version = 152;
 #pragma warning restore 169
 
                [ComVisible (true)]
index b36d3d446bc4cea25a3674a2ca7ffe6724df5484..6406b39c7dac0c0aaaf3cda71452b044c5c8527f 100644 (file)
@@ -23,9 +23,11 @@ Mono.Globalization.Unicode/SortKeyBuffer.cs
 Mono.Globalization.Unicode/Normalization.cs
 Mono.Globalization.Unicode/NormalizationTableUtil.cs
 Mono/Runtime.cs
-Mono/RuntimeStructs.cs
 Mono/RuntimeHandles.cs
+Mono/RuntimeMarshal.cs
+Mono/RuntimeStructs.cs
 Mono/SafeGPtrArrayHandle.cs
+Mono/SafeStringMarshal.cs
 Mono/DataConverter.cs
 Mono.Interop/ComInteropProxy.cs
 Mono.Interop/IDispatch.cs
diff --git a/mcs/errors/cs0163-2.cs b/mcs/errors/cs0163-2.cs
new file mode 100644 (file)
index 0000000..945ae8a
--- /dev/null
@@ -0,0 +1,13 @@
+// CS0163: Control cannot fall through from one case label `case 1:' to another
+// Line: 9
+
+public class Program
+{
+       public static void Main ()
+       {
+               switch (1) {
+                       case 1: {}
+                       default: {}
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1644-50.cs b/mcs/errors/cs1644-50.cs
new file mode 100644 (file)
index 0000000..10817d7
--- /dev/null
@@ -0,0 +1,11 @@
+// CS1644: Feature `interpolated strings' cannot be used because it is not part of the C# 5.0 language specification
+// Line: 9
+// Compiler options: -langversion:5
+
+public class Program
+{
+       public static void Main()
+       {
+               var x = $"I should not compile";
+       }
+}
index 04cfe49f1f867158e76a486138ba87982f9a1762..7200501984e2230825ba7f8dfdaf06f3cec5fba6 100644 (file)
@@ -719,9 +719,11 @@ namespace Mono.CSharp {
                                this.loc = child.Location;
                        }
 
+                       public bool RequiresEmitWithAwait { get; set; }
+
                        public override bool ContainsEmitWithAwait ()
                        {
-                               return child.ContainsEmitWithAwait ();
+                               return RequiresEmitWithAwait || child.ContainsEmitWithAwait ();
                        }
 
                        public override Expression CreateExpressionTree (ResolveContext ec)
index ceeff52fcfe7475c13f120cce8e6ec060224912c..96ac0c8db4c24aacc9f18f573adfff3d885d54da 100644 (file)
@@ -1853,7 +1853,7 @@ namespace Mono.CSharp
                                        return base_type;
                        }
 
-                       if (iface_exprs != null) {
+                       if (iface_exprs != null && this is Interface) {
                                foreach (var iface in iface_exprs) {
                                        // the interface might not have been resolved, prevents a crash, see #442144
                                        if (iface == null)
index 6783a7edbb672ef70e00d3684e3f35427ea12eab..bb2bd6e19718cad38c3cf37e8eb131b1b6581685 100644 (file)
@@ -3351,10 +3351,16 @@ boolean_literal
 interpolated_string
        : INTERPOLATED_STRING interpolations INTERPOLATED_STRING_END
          {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($1), "interpolated strings");
+
                $$ = new InterpolatedString ((StringLiteral) $1, (List<Expression>) $2, (StringLiteral) $3);
          }
        | INTERPOLATED_STRING_END
          {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($1), "interpolated strings");
+
                $$ = new InterpolatedString ((StringLiteral) $1, null, null);
          }
        ;
index f15d1a8d12dc03e3cc09b5eceec98220851233cb..e0e5b6f4748d3a4f4da983f54eb16973b1859dd8 100644 (file)
@@ -4467,6 +4467,10 @@ namespace Mono.CSharp {
                {
                        TypeSpec argument_type = a.Type;
 
+                       //
+                       // Exactly matching Expression phase
+                       //
+
                        //
                        // If argument is an anonymous function
                        //
@@ -4528,17 +4532,20 @@ namespace Mono.CSharp {
 
                                if (q != p) {
                                        //
-                                       // An inferred return type X exists for E in the context of that parameter list, and 
-                                       // the conversion from X to Y1 is better than the conversion from X to Y2
+                                       // An inferred return type X exists for E in the context of the parameter list, and
+                                       // an identity conversion exists from X to the return type of D
                                        //
-                                       argument_type = am.InferReturnType (ec, null, orig_q);
-                                       if (argument_type == null) {
-                                               // TODO: Can this be hit?
-                                               return 1;
-                                       }
+                                       var inferred_type = am.InferReturnType (ec, null, orig_q);
+                                       if (inferred_type != null) {
+                                               if (inferred_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+                                                       inferred_type = ec.BuiltinTypes.Object;
+
+                                               if (inferred_type == p)
+                                                       return 1;
 
-                                       if (argument_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
-                                               argument_type = ec.BuiltinTypes.Object;
+                                               if (inferred_type == q)
+                                                       return 2;
+                                       }
                                }
                        }
 
index aadf818066d2ad89b3d82a2b8488256753e09d9c..f805523b76e0a16f41bd3320409ad98aba4cab8e 100644 (file)
@@ -8084,11 +8084,21 @@ namespace Mono.CSharp
                        if (element == null)
                                return null;
 
-                       if (element is CompoundAssign.TargetExpression) {
-                               if (first_emit != null)
-                                       throw new InternalErrorException ("Can only handle one mutator at a time");
-                               first_emit = element;
-                               element = first_emit_temp = new LocalTemporary (element.Type);
+                       var te = element as CompoundAssign.TargetExpression;
+                       if (te != null) {
+                               for (int i = 1; i < initializers.Count; ++i) {
+                                       if (initializers [i].ContainsEmitWithAwait ()) {
+                                               te.RequiresEmitWithAwait = true;
+                                               break;
+                                       }
+                               }
+
+                               if (!te.RequiresEmitWithAwait) {
+                                       if (first_emit != null)
+                                               throw new InternalErrorException ("Can only handle one mutator at a time");
+                                       first_emit = element;
+                                       element = first_emit_temp = new LocalTemporary (element.Type);
+                               }
                        }
 
                        return Convert.ImplicitConversionRequired (
index d0341cb3b633045c48889bfa3a3f31789df36ff0..703e7ba497fef805446a5df389a8fa4f81258816 100644 (file)
@@ -5378,18 +5378,30 @@ namespace Mono.CSharp {
                                                continue;
                                        }
 
-                                       if (constant_label != null && constant_label != sl)
+                                       if (section_rc.IsUnreachable) {
+                                               //
+                                               // Common case. Previous label section end is unreachable as
+                                               // it ends with break, return, etc. For next section revert
+                                               // to reachable again unless we have constant switch block
+                                               //
+                                               section_rc = constant_label != null && constant_label != sl ?
+                                                       Reachability.CreateUnreachable () :
+                                                       new Reachability ();
+                                       } else if (prev_label != null) {
+                                               //
+                                               // Error case as control cannot fall through from one case label
+                                               //
+                                               sl.SectionStart = false;
+                                               s = new MissingBreak (prev_label);
+                                               s.MarkReachable (rc);
+                                               block.Statements.Insert (i - 1, s);
+                                               ++i;
+                                       } else if (constant_label != null && constant_label != sl) {
+                                               //
+                                               // Special case for the first unreachable label in constant
+                                               // switch block
+                                               //
                                                section_rc = Reachability.CreateUnreachable ();
-                                       else if (section_rc.IsUnreachable) {
-                                               section_rc = new Reachability ();
-                                       } else {
-                                               if (prev_label != null) {
-                                                       sl.SectionStart = false;
-                                                       s = new MissingBreak (prev_label);
-                                                       s.MarkReachable (rc);
-                                                       block.Statements.Insert (i - 1, s);
-                                                       ++i;
-                                               }
                                        }
 
                                        prev_label = sl;
diff --git a/mcs/tests/gtest-lambda-37.cs b/mcs/tests/gtest-lambda-37.cs
new file mode 100644 (file)
index 0000000..ffc669e
--- /dev/null
@@ -0,0 +1,38 @@
+using System;
+
+public class MainClass 
+{
+       static long? X<T> (T a1, Func<T, T?> a2) where T : struct
+       {
+               return 0;
+       }
+
+       static int? X<T> (T a1, Func<T, int?> a2)
+       {
+               return 0;
+       }
+
+       static double? X<T> (T a1, Func<T, double?> a2)
+       {
+               return null;
+       }
+
+       public static void Main ()
+       {
+               int? sum = X<int> (1, i => {
+                       if (i > 0)
+                               return i;
+
+                       return null;
+               });
+
+
+               int? sum2 = X (1, i => {
+                       if (i > 0)
+                               return i;
+
+                       return null;
+               });
+
+       }
+}
diff --git a/mcs/tests/test-938.cs b/mcs/tests/test-938.cs
new file mode 100644 (file)
index 0000000..17bf81e
--- /dev/null
@@ -0,0 +1,13 @@
+namespace Example
+{
+       public class A : A.InnerInterface
+       {
+               public interface InnerInterface
+               {
+               }
+
+               public static void Main ()
+               {
+               } 
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-async-86.cs b/mcs/tests/test-async-86.cs
new file mode 100644 (file)
index 0000000..0f8f71a
--- /dev/null
@@ -0,0 +1,71 @@
+using System;
+using System.Threading.Tasks;
+
+public class Program
+{
+       string Data { 
+               get {
+                       return data;
+               }
+               set {
+                       ++setter_called;
+                       data = value;
+               }
+       }
+
+       int setter_called;
+       string data = "init-";
+
+       string this [string arg] {
+               get {
+                       return i_data;
+               }
+               set {
+                       ++i_setter_called;
+                       i_data = value;
+               }
+       }
+
+       int i_setter_called;
+       string i_data = "init2-";
+
+       public static int Main()
+       {
+               var p = new Program ();
+               p.TestProperty ().Wait ();
+               if (p.data != "init-nxa123z") {
+                       return 1;
+               }
+
+               if (p.setter_called != 1)
+                       return 2;
+
+               p.TestIndexer ().Wait ();
+
+               if (p.i_data != "init2-nxa123z") {
+                       return 3;
+               }
+
+               if (p.i_setter_called != 1)
+                       return 4;
+
+               return 0;
+       }
+
+       async Task TestProperty ()
+       {
+               Data += "n" + await StringValue () + "a" + 123.ToString () + "z";
+       }
+
+       async Task TestIndexer ()
+       {
+               string arg = "foo";
+               this[arg] += "n" + await StringValue () + "a" + 123.ToString () + "z";
+       }
+
+       async Task<string> StringValue ()
+       {
+               await Task.Yield ();
+               return "x";
+       }
+}
\ No newline at end of file
index 2496afc80a80fee6f31a0ed8768921facdb7e772..79e1b18bf10b992f0e7b5578a81fb54ac33b8a94 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-lambda-37.cs">
+    <type name="MainClass">
+      <method name="System.Nullable`1[System.Int64] X[T](T, System.Func`2[T,System.Nullable`1[T]])" attrs="145">
+        <size>16</size>
+      </method>
+      <method name="System.Nullable`1[System.Int32] X[T](T, System.Func`2[T,System.Nullable`1[System.Int32]])" attrs="145">
+        <size>15</size>
+      </method>
+      <method name="System.Nullable`1[System.Double] X[T](T, System.Func`2[T,System.Nullable`1[System.Double]])" attrs="145">
+        <size>18</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>74</size>
+      </method>
+      <method name="System.Nullable`1[System.Int32] &lt;Main&gt;m__0(Int32)" attrs="145">
+        <size>37</size>
+      </method>
+      <method name="System.Nullable`1[System.Int32] &lt;Main&gt;m__1(Int32)" attrs="145">
+        <size>37</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-linq-01.cs">
     <type name="from.C">
       <method name="Void Main()" attrs="150">
       </method>
     </type>
   </test>
+  <test name="test-938.cs">
+    <type name="Example.A">
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-94.cs">
     <type name="Base">
       <method name="Int32 IVehicle.Start()" attrs="481">
       </method>
     </type>
   </test>
+  <test name="test-async-86.cs">
+    <type name="Program">
+      <method name="System.String get_Data()" attrs="2177">
+        <size>15</size>
+      </method>
+      <method name="Void set_Data(System.String)" attrs="2177">
+        <size>23</size>
+      </method>
+      <method name="System.String get_Item(System.String)" attrs="2177">
+        <size>15</size>
+      </method>
+      <method name="Void set_Item(System.String, System.String)" attrs="2177">
+        <size>23</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>134</size>
+      </method>
+      <method name="System.Threading.Tasks.Task TestProperty()" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task TestIndexer()" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.String] StringValue()" attrs="129">
+        <size>33</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>29</size>
+      </method>
+    </type>
+    <type name="Program+&lt;TestProperty&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>314</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="Program+&lt;TestIndexer&gt;c__async1">
+      <method name="Void MoveNext()" attrs="486">
+        <size>337</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="Program+&lt;StringValue&gt;c__async2">
+      <method name="Void MoveNext()" attrs="486">
+        <size>171</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">
index 55c2aeb4283b7e621624cbb808044cac3accf1ab..dd48a6f05b183ab8ea2f547135d76393ebaf9a95 100644 (file)
@@ -59,6 +59,9 @@ namespace CorCompare
                                { "h|?|help",
                                        "Show this message and exit.",
                                        v => showHelp = v != null },
+                               { "contract-api",
+                                       "Produces contract API with all members at each level of inheritance hierarchy",
+                                       v => FullAPISet = v != null },
                        };
 
                        var asms = options.Parse (args);
@@ -116,6 +119,7 @@ namespace CorCompare
 
                internal static bool AbiMode { get; private set; }
                internal static bool FollowForwarders { get; private set; }
+               internal static bool FullAPISet { get; set; }
        }
 
        public class Utils {
@@ -538,7 +542,7 @@ namespace CorCompare
                                        members.Add (new ConstructorData (writer, ctors));
                                }
 
-                               PropertyDefinition[] properties = GetProperties (type);
+                               PropertyDefinition[] properties = GetProperties (type, Driver.FullAPISet);
                                if (properties.Length > 0) {
                                        Array.Sort (properties, PropertyDefinitionComparer.Default);
                                        members.Add (new PropertyData (writer, properties));
@@ -550,7 +554,7 @@ namespace CorCompare
                                        members.Add (new EventData (writer, events));
                                }
 
-                               MethodDefinition [] methods = GetMethods (type);
+                               MethodDefinition [] methods = GetMethods (type, Driver.FullAPISet);
                                if (methods.Length > 0) {
                                        Array.Sort (methods, MethodDefinitionComparer.Default);
                                        members.Add (new MethodData (writer, methods));
@@ -693,53 +697,91 @@ namespace CorCompare
                }
 
 
-               internal static PropertyDefinition [] GetProperties (TypeDefinition type) {
-                       ArrayList list = new ArrayList ();
+               internal static PropertyDefinition [] GetProperties (TypeDefinition type, bool fullAPI) {
+                       var list = new List<PropertyDefinition> ();
+
+                       var t = type;
+                       do {
+                               var properties = t.Properties;//type.GetProperties (flags);
+                               foreach (PropertyDefinition property in properties) {
+                                       MethodDefinition getMethod = property.GetMethod;
+                                       MethodDefinition setMethod = property.SetMethod;
 
-                       var properties = type.Properties;//type.GetProperties (flags);
-                       foreach (PropertyDefinition property in properties) {
-                               MethodDefinition getMethod = property.GetMethod;
-                               MethodDefinition setMethod = property.SetMethod;
+                                       bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
+                                       bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
 
-                               bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
-                               bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
+                                       // if neither the getter or setter should be documented, then
+                                       // skip the property
+                                       if (hasGetter || hasSetter) {
+
+                                               if (t != type && list.Any (l => l.Name == property.Name))
+                                                       continue;
 
-                               // if neither the getter or setter should be documented, then
-                               // skip the property
-                               if (hasGetter || hasSetter) {
-                                       list.Add (property);
+                                               list.Add (property);
+                                       }
                                }
-                       }
 
-                       return (PropertyDefinition []) list.ToArray (typeof (PropertyDefinition));
+                               if (!fullAPI)
+                                       break;
+
+                               if (t.IsInterface || t.IsEnum)
+                                       break;
+
+                               if (t.BaseType == null || t.BaseType.FullName == "System.Object")
+                                       t = null;
+                               else
+                                       t = t.BaseType.Resolve ();
+
+                       } while (t != null);
+
+                       return list.ToArray ();
                }
 
-               private MethodDefinition[] GetMethods (TypeDefinition type)
+               private MethodDefinition[] GetMethods (TypeDefinition type, bool fullAPI)
                {
-                       ArrayList list = new ArrayList ();
+                       var list = new List<MethodDefinition> ();
 
-                       var methods = type.Methods;//type.GetMethods (flags);
-                       foreach (MethodDefinition method in methods) {
-                               if (method.IsSpecialName && !method.Name.StartsWith ("op_", StringComparison.Ordinal))
-                                       continue;
+                       var t = type;
+                       do {
+                               var methods = t.Methods;//type.GetMethods (flags);
+                               foreach (MethodDefinition method in methods) {
+                                       if (method.IsSpecialName && !method.Name.StartsWith ("op_", StringComparison.Ordinal))
+                                               continue;
 
-                               // we're only interested in public or protected members
-                               if (!MustDocumentMethod(method))
-                                       continue;
+                                       // we're only interested in public or protected members
+                                       if (!MustDocumentMethod (method))
+                                               continue;
+
+                                       if (t == type && IsFinalizer (method)) {
+                                               string name = method.DeclaringType.Name;
+                                               int arity = name.IndexOf ('`');
+                                               if (arity > 0)
+                                                       name = name.Substring (0, arity);
 
-                               if (IsFinalizer (method)) {
-                                       string name = method.DeclaringType.Name;
-                                       int arity = name.IndexOf ('`');
-                                       if (arity > 0)
-                                               name = name.Substring (0, arity);
+                                               method.Name = "~" + name;
+                                       }
+
+                                       // TODO: Better check
+                                       if (t != type && list.Any (l => l.DeclaringType != method.DeclaringType && l.Name == method.Name && l.Parameters.Count == method.Parameters.Count))
+                                               continue;
 
-                                       method.Name = "~" + name;
+                                       list.Add (method);
                                }
 
-                               list.Add (method);
-                       }
+                               if (!fullAPI)
+                                       break;
 
-                       return (MethodDefinition []) list.ToArray (typeof (MethodDefinition));
+                               if (!t.IsInterface || t.IsEnum)
+                                       break;
+
+                               if (t.BaseType == null || t.BaseType.FullName == "System.Object")
+                                       t = null;
+                               else
+                                       t = t.BaseType.Resolve ();
+
+                       } while (t != null);
+
+                       return list.ToArray ();
                }
 
                static bool IsFinalizer (MethodDefinition method)
index bc8fddc327d675bd2ce58402e644d0ee8cbde774..28279d9322a8a3e593b40857f7b9758bfcfa72ce 100644 (file)
                </type>
                <type fullname="System.Runtime.Remoting.Proxies.TransparentProxy" preserve="fields">
                        <method name="LoadRemoteFieldNew" />
+                       <method name="StoreRemoteField" />
                </type>
                <type fullname="System.Runtime.Remoting.RemotingServices">
                        <method name="SerializeCallData" />
index 9da6edc106d5e91eedaef5e5c4c59e295d8ef8cc..e99f07415765bc21b618798f6d7c132a22d0a1e1 100644 (file)
@@ -424,8 +424,13 @@ namespace Xamarin.ApiDiff {
                                if (tgtAbstract) {
                                        change.AppendAdded ("abstract", true).Append (" ");
                                } else if (srcWord != tgtWord) {
-                                       if (!tgtFinal)
-                                               change.AppendModified (srcWord, tgtWord, breaking).Append (" ");
+                                       if (!tgtFinal) {
+                                               if (State.IgnoreVirtualChanges) {
+                                                       change.HasIgnoredChanges = true;
+                                               } else {
+                                                       change.AppendModified (srcWord, tgtWord, breaking).Append (" ");
+                                               }
+                                       }
                                } else if (tgtWord.Length > 0) {
                                        change.Append (tgtWord).Append (" ");
                                } else if (srcWord.Length > 0) {
@@ -437,7 +442,11 @@ namespace Xamarin.ApiDiff {
                                if (tgtFinal) {
                                        change.Append ("final ");
                                } else {
-                                       change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change.
+                                       if (srcVirtual && !tgtVirtual && State.IgnoreVirtualChanges) {
+                                               change.HasIgnoredChanges = true;
+                                       } else {
+                                               change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change.
+                                       }
                                }
                        } else {
                                if (tgtFinal && srcVirtual) {
index 8ec7c50ae58ac61949a50fe4b3d51f45278dff33..50ed3496b0c2a2a142d16aa6579e217e86d6081b 100644 (file)
@@ -2298,7 +2298,7 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
 {
        struct _WapiHandle_file *file_handle;
        gpointer handle;
-       int thr_ret, fd;
+       int fd;
        const gchar *name;
        gboolean ok;
        
@@ -2327,8 +2327,7 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
 
        handle = GINT_TO_POINTER (fd);
 
-       thr_ret = mono_os_mutex_lock (&stdhandle_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_lock (&stdhandle_mutex);
 
        ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
                                  (gpointer *)&file_handle);
@@ -2346,8 +2345,7 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
        }
        
   done:
-       thr_ret = mono_os_mutex_unlock (&stdhandle_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&stdhandle_mutex);
        
        return(handle);
 }
index 20ad800c0485190fef7af966b92544b107ff14d9..40ab66c77b43b28e06421f62e3d547249230daf9 100644 (file)
@@ -1043,25 +1043,19 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
                        mono_process = (struct MonoProcess *) g_malloc0 (sizeof (struct MonoProcess));
                        mono_process->pid = pid;
                        mono_process->handle_count = 1;
-                       if (mono_os_sem_init (&mono_process->exit_sem, 0) != 0) {
-                               /* If we can't create the exit semaphore, we just don't add anything
-                                * to our list of mono processes. Waiting on the process will return 
-                                * immediately. */
-                               g_warning ("%s: could not create exit semaphore for process.", strerror (errno));
-                               g_free (mono_process);
-                       } else {
-                               /* Keep the process handle artificially alive until the process
-                                * exits so that the information in the handle isn't lost. */
-                               mono_w32handle_ref (handle);
-                               mono_process->handle = handle;
+                       mono_os_sem_init (&mono_process->exit_sem, 0);
 
-                               process_handle_data->mono_process = mono_process;
+                       /* Keep the process handle artificially alive until the process
+                        * exits so that the information in the handle isn't lost. */
+                       mono_w32handle_ref (handle);
+                       mono_process->handle = handle;
 
-                               mono_os_mutex_lock (&mono_processes_mutex);
-                               mono_process->next = mono_processes;
-                               mono_processes = mono_process;
-                               mono_os_mutex_unlock (&mono_processes_mutex);
-                       }
+                       process_handle_data->mono_process = mono_process;
+
+                       mono_os_mutex_lock (&mono_processes_mutex);
+                       mono_process->next = mono_processes;
+                       mono_processes = mono_process;
+                       mono_os_mutex_unlock (&mono_processes_mutex);
 
                        if (process_info != NULL) {
                                process_info->hProcess = handle;
@@ -2815,19 +2809,13 @@ process_wait (gpointer handle, guint32 timeout, gboolean alertable)
                        ret = mono_os_sem_wait (&mp->exit_sem, alertable ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
                }
 
-               if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): sem_timedwait failure: %s", 
-                                  __func__, handle, timeout, g_strerror (errno));
-                       /* Should we return a failure here? */
-               }
-
-               if (ret == 0) {
+               if (ret == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
                        /* Success, process has exited */
                        mono_os_sem_post (&mp->exit_sem);
                        break;
                }
 
-               if (timeout == 0) {
+               if (ret == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
                        return WAIT_TIMEOUT;
                }
@@ -2838,7 +2826,7 @@ process_wait (gpointer handle, guint32 timeout, gboolean alertable)
                        return WAIT_TIMEOUT;
                }
                
-               if (alertable && _wapi_thread_cur_apc_pending ()) {
+               if (alertable && ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
                        return WAIT_IO_COMPLETION;
                }
index b1d9c1ba509b45542d88ca895c3b937ec344c32f..8fb0e2703bd21386f9991b1ae18333a7c390abed 100644 (file)
@@ -31,7 +31,8 @@ int
 _wapi_shm_sem_lock (int sem)
 {
        DEBUGLOG ("%s: locking nosem %d", __func__, sem);
-       return mono_os_mutex_lock (&noshm_sems[sem]);
+       mono_os_mutex_lock (&noshm_sems[sem]);
+       return 0;
 }
 
 int
@@ -45,5 +46,6 @@ int
 _wapi_shm_sem_unlock (int sem)
 {
        DEBUGLOG ("%s: unlocking nosem %d", __func__, sem);
-       return mono_os_mutex_unlock (&noshm_sems[sem]);
+       mono_os_mutex_unlock (&noshm_sems[sem]);
+       return 0;
 }
index 82150dbe0574a8f5477b22d387e4373587e2d03f..7d0c384d0c15ed40a622d0cef57e605d3af5a5ab 100644 (file)
@@ -83,7 +83,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 151
+#define MONO_CORLIB_VERSION 152
 
 typedef struct
 {
index 9c435d27b50df9b3775470b1137c1f087b7b74cd..4bad7dc5ed6d85719bd7426b3e906655c833c127 100644 (file)
@@ -921,6 +921,7 @@ mono_assembly_addref (MonoAssembly *assembly)
 #define WINFX_KEY "31bf3856ad364e35"
 #define ECMA_KEY "b77a5c561934e089"
 #define MSFINAL_KEY "b03f5f7f11d50a3a"
+#define COMPACTFRAMEWORK_KEY "969db8053d3322ac"
 
 typedef struct {
        const char *name;
@@ -929,20 +930,34 @@ typedef struct {
 } KeyRemapEntry;
 
 static KeyRemapEntry key_remap_table[] = {
+       { "CustomMarshalers", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
        { "Microsoft.CSharp", WINFX_KEY, MSFINAL_KEY },
+       { "Microsoft.VisualBasic", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
        { "System", SILVERLIGHT_KEY, ECMA_KEY },
+       { "System", COMPACTFRAMEWORK_KEY, ECMA_KEY },
        { "System.ComponentModel.Composition", WINFX_KEY, ECMA_KEY },
        { "System.ComponentModel.DataAnnotations", "ddd0da4d3e678217", WINFX_KEY },
        { "System.Core", SILVERLIGHT_KEY, ECMA_KEY },
+       { "System.Core", COMPACTFRAMEWORK_KEY, ECMA_KEY },
+       { "System.Data", COMPACTFRAMEWORK_KEY, ECMA_KEY },
+       { "System.Data.DataSetExtensions", COMPACTFRAMEWORK_KEY, ECMA_KEY },
+       { "System.Drawing", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
+       { "System.Messaging", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
        // FIXME: MS uses MSFINAL_KEY for .NET 4.5
        { "System.Net", SILVERLIGHT_KEY, MSFINAL_KEY },
        { "System.Numerics", WINFX_KEY, ECMA_KEY },
        { "System.Runtime.Serialization", SILVERLIGHT_KEY, ECMA_KEY },
+       { "System.Runtime.Serialization", COMPACTFRAMEWORK_KEY, ECMA_KEY },
        { "System.ServiceModel", WINFX_KEY, ECMA_KEY },
+       { "System.ServiceModel", COMPACTFRAMEWORK_KEY, ECMA_KEY },
        { "System.ServiceModel.Web", SILVERLIGHT_KEY, WINFX_KEY },
+       { "System.Web.Services", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
        { "System.Windows", SILVERLIGHT_KEY, MSFINAL_KEY },
+       { "System.Windows.Forms", COMPACTFRAMEWORK_KEY, ECMA_KEY },
        { "System.Xml", SILVERLIGHT_KEY, ECMA_KEY },
+       { "System.Xml", COMPACTFRAMEWORK_KEY, ECMA_KEY },
        { "System.Xml.Linq", WINFX_KEY, ECMA_KEY },
+       { "System.Xml.Linq", COMPACTFRAMEWORK_KEY, ECMA_KEY },
        { "System.Xml.Serialization", WINFX_KEY, ECMA_KEY }
 };
 
@@ -1984,6 +1999,7 @@ mono_assembly_name_free (MonoAssemblyName *aname)
        g_free ((void *) aname->name);
        g_free ((void *) aname->culture);
        g_free ((void *) aname->hash_value);
+       g_free ((guint8*) aname->public_key);
 }
 
 static gboolean
index e76a3a3bfb7b6f581f9bceb8aa2eb711e4b01c38..41510b486e88139695f0f0109332effe0b59557f 100644 (file)
@@ -829,6 +829,11 @@ mono_gc_clear_domain (MonoDomain *domain)
 {
 }
 
+void
+mono_gc_suspend_finalizers (void)
+{
+}
+
 int
 mono_gc_get_suspend_signal (void)
 {
index 2fa32269a80ee85433a4f042d50d5e454bdcbaa5..b5a19af282f4aa6e588dc7f1f28aef511acd9a7e 100644 (file)
@@ -161,9 +161,11 @@ void  mono_gc_register_for_finalization (MonoObject *obj, void *user_data);
 void  mono_gc_add_memory_pressure (gint64 value);
 MONO_API int   mono_gc_register_root (char *start, size_t size, MonoGCDescriptor descr, MonoGCRootSource source, const char *msg);
 void  mono_gc_deregister_root (char* addr);
-void  mono_gc_finalize_domain (MonoDomain *domain, volatile gboolean *suspend);
+void  mono_gc_finalize_domain (MonoDomain *domain);
 void  mono_gc_run_finalize (void *obj, void *data);
 void  mono_gc_clear_domain (MonoDomain * domain);
+/* Signal early termination of finalizer processing inside the gc */
+void  mono_gc_suspend_finalizers (void);
 
 
 /* 
index f077719380c8e178c8dbfeb36f33d8b686c07219..350d439bee3e05e6e64e6afd62b9f5a12f5c5578 100644 (file)
 #endif
 
 typedef struct DomainFinalizationReq {
+       gint32 ref;
        MonoDomain *domain;
-       HANDLE done_event;
+       MonoCoopSem done;
 } DomainFinalizationReq;
 
-static gboolean gc_disabled = FALSE;
+static gboolean gc_disabled;
 
-static gboolean finalizing_root_domain = FALSE;
+static gboolean finalizing_root_domain;
 
-gboolean log_finalizers = FALSE;
-gboolean mono_do_not_finalize = FALSE;
-gchar **mono_do_not_finalize_class_names = NULL;
+gboolean log_finalizers;
+gboolean mono_do_not_finalize;
+volatile gboolean suspend_finalizers;
+gchar **mono_do_not_finalize_class_names ;
 
 #define mono_finalizer_lock() mono_coop_mutex_lock (&finalizer_mutex)
 #define mono_finalizer_unlock() mono_coop_mutex_unlock (&finalizer_mutex)
 static MonoCoopMutex finalizer_mutex;
 static MonoCoopMutex reference_queue_mutex;
 
-static GSList *domains_to_finalize= NULL;
-static MonoMList *threads_to_finalize = NULL;
+static GSList *domains_to_finalize;
+static MonoMList *threads_to_finalize;
 
 static gboolean finalizer_thread_exited;
 /* Uses finalizer_mutex */
@@ -74,12 +76,20 @@ static MonoCoopCond exited_cond;
 
 static MonoInternalThread *gc_thread;
 
+#ifdef TARGET_WIN32
+static HANDLE pending_done_event;
+#else
+static gboolean pending_done;
+static MonoCoopCond pending_done_cond;
+static MonoCoopMutex pending_done_mutex;
+#endif
+
 static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*));
 
 static void reference_queue_proccess_all (void);
 static void mono_reference_queue_cleanup (void);
 static void reference_queue_clear_for_domain (MonoDomain *domain);
-static HANDLE pending_done_event;
+
 
 static guint32
 guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
@@ -93,6 +103,51 @@ guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
        return result;
 }
 
+typedef struct {
+       MonoCoopCond *cond;
+       MonoCoopMutex *mutex;
+} BreakCoopAlertableWaitUD;
+
+static inline void
+break_coop_alertable_wait (gpointer user_data)
+{
+       BreakCoopAlertableWaitUD *ud = (BreakCoopAlertableWaitUD*)user_data;
+
+       mono_coop_mutex_lock (ud->mutex);
+       mono_coop_cond_signal (ud->cond);
+       mono_coop_mutex_unlock (ud->mutex);
+}
+
+/*
+ * coop_cond_timedwait_alertable:
+ *
+ *   Wait on COND/MUTEX. If ALERTABLE is non-null, the wait can be interrupted.
+ * In that case, *ALERTABLE will be set to TRUE, and 0 is returned.
+ */
+static inline gint
+coop_cond_timedwait_alertable (MonoCoopCond *cond, MonoCoopMutex *mutex, guint32 timeout_ms, gboolean *alertable)
+{
+       int res;
+
+       if (alertable) {
+               BreakCoopAlertableWaitUD ud;
+
+               *alertable = FALSE;
+               ud.cond = cond;
+               ud.mutex = mutex;
+               mono_thread_info_install_interrupt (break_coop_alertable_wait, &ud, alertable);
+               if (*alertable)
+                       return 0;
+       }
+       res = mono_coop_cond_timedwait (cond, mutex, timeout_ms);
+       if (alertable) {
+               mono_thread_info_uninstall_interrupt (alertable);
+               if (*alertable)
+                       return 0;
+       }
+       return res;
+}
+
 static gboolean
 add_thread_to_finalize (MonoInternalThread *thread, MonoError *error)
 {
@@ -105,7 +160,6 @@ add_thread_to_finalize (MonoInternalThread *thread, MonoError *error)
        return is_ok (error);
 }
 
-static volatile gboolean suspend_finalizers = FALSE;
 /* 
  * actually, we might want to queue the finalize requests in a separate thread,
  * but we need to be careful about the execution domain of the thread...
@@ -382,9 +436,10 @@ gboolean
 mono_domain_finalize (MonoDomain *domain, guint32 timeout) 
 {
        DomainFinalizationReq *req;
-       guint32 res;
-       HANDLE done_event;
        MonoInternalThread *thread = mono_thread_internal_current ();
+       gint res;
+       gboolean ret;
+       gint64 start;
 
 #if defined(__native_client__)
        return FALSE;
@@ -408,14 +463,10 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
 
        mono_gc_collect (mono_gc_max_generation ());
 
-       done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
-       if (done_event == NULL) {
-               return FALSE;
-       }
-
        req = g_new0 (DomainFinalizationReq, 1);
+       req->ref = 2;
        req->domain = domain;
-       req->done_event = done_event;
+       mono_coop_sem_init (&req->done, 0);
 
        if (domain == mono_get_root_domain ())
                finalizing_root_domain = TRUE;
@@ -431,23 +482,65 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
 
        if (timeout == -1)
                timeout = INFINITE;
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
 
-       while (TRUE) {
-               res = guarded_wait (done_event, timeout, TRUE);
-               /* printf ("WAIT RES: %d.\n", res); */
+       ret = TRUE;
 
-               if (res == WAIT_IO_COMPLETION) {
-                       if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0)
-                               return FALSE;
-               } else if (res == WAIT_TIMEOUT) {
-                       /* We leak the handle here */
-                       return FALSE;
+       for (;;) {
+               if (timeout == INFINITE) {
+                       res = mono_coop_sem_wait (&req->done, MONO_SEM_FLAGS_ALERTABLE);
                } else {
+                       gint64 elapsed = mono_msec_ticks () - start;
+                       if (elapsed >= timeout) {
+                               ret = FALSE;
+                               break;
+                       }
+
+                       res = mono_coop_sem_timedwait (&req->done, timeout - elapsed, MONO_SEM_FLAGS_ALERTABLE);
+               }
+
+               if (res == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
                        break;
+               } else if (res == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
+                       if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0) {
+                               ret = FALSE;
+                               break;
+                       }
+               } else if (res == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
+                       ret = FALSE;
+                       break;
+               } else {
+                       g_error ("%s: unknown result %d", __func__, res);
                }
        }
 
-       CloseHandle (done_event);
+       if (!ret) {
+               /* Try removing the req from domains_to_finalize:
+                *  - if it's not found: the domain is being finalized,
+                *     so we the ref count is already decremented
+                *  - if it's found: the domain is not yet being finalized,
+                *     so we can safely decrement the ref */
+
+               gboolean found;
+
+               mono_finalizer_lock ();
+
+               found = g_slist_index (domains_to_finalize, req) != -1;
+               if (found)
+                       domains_to_finalize = g_slist_remove (domains_to_finalize, req);
+
+               mono_finalizer_unlock ();
+
+               if (found) {
+                       /* We have to decrement it wherever we
+                        * remove it from domains_to_finalize */
+                       if (InterlockedDecrement (&req->ref) != 1)
+                               g_error ("%s: req->ref should be 1, as we are the first one to decrement it", __func__);
+               }
+
+               goto done;
+       }
 
        if (domain == mono_get_root_domain ()) {
                mono_threadpool_ms_cleanup ();
@@ -456,7 +549,13 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
 
        mono_profiler_appdomain_event (domain, MONO_PROFILE_END_UNLOAD);
 
-       return TRUE;
+done:
+       if (InterlockedDecrement (&req->ref) == 0) {
+               mono_coop_sem_destroy (&req->done);
+               g_free (req);
+       }
+
+       return ret;
 }
 
 void
@@ -528,11 +627,24 @@ ves_icall_System_GC_WaitForPendingFinalizers (void)
        if (gc_thread == NULL)
                return;
 
+#ifdef TARGET_WIN32
        ResetEvent (pending_done_event);
        mono_gc_finalize_notify ();
        /* g_print ("Waiting for pending finalizers....\n"); */
        guarded_wait (pending_done_event, INFINITE, TRUE);
        /* g_print ("Done pending....\n"); */
+#else
+       gboolean alerted = FALSE;
+       mono_coop_mutex_lock (&pending_done_mutex);
+       pending_done = FALSE;
+       mono_gc_finalize_notify ();
+       while (!pending_done) {
+               coop_cond_timedwait_alertable (&pending_done_cond, &pending_done_mutex, INFINITE, &alerted);
+               if (alerted)
+                       break;
+       }
+       mono_coop_mutex_unlock (&pending_done_mutex);
+#endif
 }
 
 void
@@ -622,8 +734,14 @@ mono_gc_GCHandle_CheckCurrentDomain (guint32 gchandle)
 }
 
 static MonoCoopSem finalizer_sem;
-static volatile gboolean finished=FALSE;
+static volatile gboolean finished;
 
+/*
+ * mono_gc_finalize_notify:
+ *
+ *   Notify the finalizer thread that finalizers etc.
+ * are available to be processed.
+ */
 void
 mono_gc_finalize_notify (void)
 {
@@ -689,9 +807,24 @@ collect_objects (gpointer key, gpointer value, gpointer user_data)
  *  Run the finalizers of all finalizable objects in req->domain.
  */
 static void
-finalize_domain_objects (DomainFinalizationReq *req)
+finalize_domain_objects (void)
 {
-       MonoDomain *domain = req->domain;
+       DomainFinalizationReq *req = NULL;
+       MonoDomain *domain;
+
+       if (domains_to_finalize) {
+               mono_finalizer_lock ();
+               if (domains_to_finalize) {
+                       req = (DomainFinalizationReq *)domains_to_finalize->data;
+                       domains_to_finalize = g_slist_remove (domains_to_finalize, req);
+               }
+               mono_finalizer_unlock ();
+       }
+
+       if (!req)
+               return;
+
+       domain = req->domain;
 
        /* Process finalizers which are already in the queue */
        mono_gc_invoke_finalizers ();
@@ -718,7 +851,7 @@ finalize_domain_objects (DomainFinalizationReq *req)
                g_ptr_array_free (objs, TRUE);
        }
 #elif defined(HAVE_SGEN_GC)
-       mono_gc_finalize_domain (domain, &suspend_finalizers);
+       mono_gc_finalize_domain (domain);
        mono_gc_invoke_finalizers ();
 #endif
 
@@ -726,21 +859,25 @@ finalize_domain_objects (DomainFinalizationReq *req)
        reference_queue_clear_for_domain (domain);
        
        /* printf ("DONE.\n"); */
-       SetEvent (req->done_event);
+       mono_coop_sem_post (&req->done);
 
-       /* The event is closed in mono_domain_finalize if we get here */
-       g_free (req);
+       if (InterlockedDecrement (&req->ref) == 0) {
+               /* mono_domain_finalize already returned, and
+                * doesn't hold a reference to req anymore. */
+               mono_coop_sem_destroy (&req->done);
+               g_free (req);
+       }
 }
 
 static guint32
 finalizer_thread (gpointer unused)
 {
        MonoError error;
+       gboolean wait = TRUE;
+
        mono_thread_set_name_internal (mono_thread_internal_current (), mono_string_new (mono_get_root_domain (), "Finalizer"), FALSE, &error);
        mono_error_assert_ok (&error);
 
-       gboolean wait = TRUE;
-
        /* Register a hazard free queue pump callback */
        mono_hazard_pointer_install_free_queue_size_callback (hazard_free_queue_is_too_big);
 
@@ -766,18 +903,7 @@ finalizer_thread (gpointer unused)
 
                mono_attach_maybe_start ();
 
-               if (domains_to_finalize) {
-                       mono_finalizer_lock ();
-                       if (domains_to_finalize) {
-                               DomainFinalizationReq *req = (DomainFinalizationReq *)domains_to_finalize->data;
-                               domains_to_finalize = g_slist_remove (domains_to_finalize, req);
-                               mono_finalizer_unlock ();
-
-                               finalize_domain_objects (req);
-                       } else {
-                               mono_finalizer_unlock ();
-                       }
-               }                               
+               finalize_domain_objects ();
 
                /* If finished == TRUE, mono_gc_cleanup has been called (from mono_runtime_cleanup),
                 * before the domain is unloaded.
@@ -791,11 +917,18 @@ finalizer_thread (gpointer unused)
                hazard_free_queue_pump ();
 
                /* Avoid posting the pending done event until there are pending finalizers */
-               if (mono_coop_sem_timedwait (&finalizer_sem, 0, MONO_SEM_FLAGS_NONE) == 0) {
+               if (mono_coop_sem_timedwait (&finalizer_sem, 0, MONO_SEM_FLAGS_NONE) == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
                        /* Don't wait again at the start of the loop */
                        wait = FALSE;
                } else {
+#ifdef TARGET_WIN32
                        SetEvent (pending_done_event);
+#else
+                       mono_coop_mutex_lock (&pending_done_mutex);
+                       pending_done = TRUE;
+                       mono_coop_cond_signal (&pending_done_cond);
+                       mono_coop_mutex_unlock (&pending_done_mutex);
+#endif
                }
        }
 
@@ -837,8 +970,14 @@ mono_gc_init (void)
                return;
        }
 
+#ifdef TARGET_WIN32
        pending_done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
        g_assert (pending_done_event);
+#else
+       mono_coop_cond_init (&pending_done_cond);
+       mono_coop_mutex_init (&pending_done_mutex);
+#endif
+
        mono_coop_cond_init (&exited_cond);
        mono_coop_sem_init (&finalizer_sem, 0);
 
@@ -885,6 +1024,7 @@ mono_gc_cleanup (void)
 
                                /* Set a flag which the finalizer thread can check */
                                suspend_finalizers = TRUE;
+                               mono_gc_suspend_finalizers ();
 
                                /* Try to abort the thread, in the hope that it is running managed code */
                                mono_thread_internal_abort (gc_thread);
index 757ed8c5be79f0dbc270a476f5eb2c9c359d997a..d529af28d6c79fc479268620d7795659c05b27d8 100644 (file)
@@ -68,6 +68,13 @@ ICALL(RTCLASS_1, "GetTypeFromClass", ves_icall_Mono_RuntimeClassHandle_GetTypeFr
 ICALL_TYPE(RTPTRARRAY, "Mono.RuntimeGPtrArrayHandle", RTPTRARRAY_1)
 ICALL(RTPTRARRAY_1, "GPtrArrayFree", ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree)
 
+ICALL_TYPE(RTMARSHAL, "Mono.RuntimeMarshal", RTMARSHAL_1)
+ICALL(RTMARSHAL_1, "FreeAssemblyName", ves_icall_Mono_RuntimeMarshal_FreeAssemblyName)
+
+ICALL_TYPE(SAFESTRMARSHAL, "Mono.SafeStringMarshal", SAFESTRMARSHAL_1)
+ICALL(SAFESTRMARSHAL_1, "GFree", ves_icall_Mono_SafeStringMarshal_GFree)
+ICALL(SAFESTRMARSHAL_2, "StringToUtf8", ves_icall_Mono_SafeStringMarshal_StringToUtf8)
+
 #ifndef PLATFORM_RO_FS
 ICALL_TYPE(KPAIR, "Mono.Security.Cryptography.KeyPairPersistence", KPAIR_1)
 ICALL(KPAIR_1, "_CanSecure", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure)
@@ -460,8 +467,7 @@ ICALL(OBJ_1, "GetType", ves_icall_System_Object_GetType)
 ICALL(OBJ_2, "InternalGetHashCode", mono_object_hash)
 ICALL(OBJ_3, "MemberwiseClone", ves_icall_System_Object_MemberwiseClone)
 
-ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_1)
-ICALL(ASSEM_1, "FillName", ves_icall_System_Reflection_Assembly_FillName)
+ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_1a)
 ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId)
 ICALL(ASSEM_2, "GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly)
 ICALL(ASSEM_3, "GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly)
@@ -490,8 +496,9 @@ ICALL(ASSEM_24, "get_global_assembly_cache", ves_icall_System_Reflection_Assembl
 ICALL(ASSEM_25, "get_location", ves_icall_System_Reflection_Assembly_get_location)
 ICALL(ASSEM_26, "load_with_partial_name", ves_icall_System_Reflection_Assembly_load_with_partial_name)
 
-ICALL_TYPE(ASSEMN, "System.Reflection.AssemblyName", ASSEMN_1)
-ICALL(ASSEMN_1, "ParseName", ves_icall_System_Reflection_AssemblyName_ParseName)
+ICALL_TYPE(ASSEMN, "System.Reflection.AssemblyName", ASSEMN_0)
+ICALL(ASSEMN_0, "GetNativeName", ves_icall_System_Reflection_AssemblyName_GetNativeName)
+ICALL(ASSEMN_3, "ParseAssemblyName", ves_icall_System_Reflection_AssemblyName_ParseAssemblyName)
 ICALL(ASSEMN_2, "get_public_token", mono_digest_get_public_token)
 
 ICALL_TYPE(CATTR_DATA, "System.Reflection.CustomAttributeData", CATTR_DATA_1)
@@ -752,7 +759,7 @@ ICALL(RT_9, "GetGenericParameterPosition", ves_icall_RuntimeType_GetGenericParam
 ICALL(RT_10, "GetInterfaceMapData", ves_icall_RuntimeType_GetInterfaceMapData)
 ICALL(RT_11, "GetInterfaces", ves_icall_RuntimeType_GetInterfaces)
 ICALL(RT_12, "GetMethodsByName_native", ves_icall_RuntimeType_GetMethodsByName_native)
-ICALL(RT_13, "GetNestedTypes_internal", ves_icall_RuntimeType_GetNestedTypes)
+ICALL(RT_13, "GetNestedTypes_native", ves_icall_RuntimeType_GetNestedTypes_native)
 ICALL(RT_14, "GetPacking", ves_icall_RuntimeType_GetPacking)
 ICALL(RT_15, "GetPropertiesByName_native", ves_icall_RuntimeType_GetPropertiesByName_native)
 ICALL(RT_16, "GetTypeCodeImplInternal", ves_icall_type_GetTypeCodeInternal)
index 25273d463d9d72c50a947eb45997a4ac60cde09b..2e3240354898d39ce5f3facc3d931fe501e45420 100644 (file)
@@ -1536,9 +1536,24 @@ ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
 }
 
 ICALL_EXPORT void
-ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array, MonoBoolean freeSeg)
+ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
 {
-       g_ptr_array_free (ptr_array, freeSeg);
+       g_ptr_array_free (ptr_array, TRUE);
+}
+
+ICALL_EXPORT void
+ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
+{
+       g_free (c_str);
+}
+
+ICALL_EXPORT char*
+ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
+{
+       MonoError error;
+       char *res = mono_string_to_utf8_checked (s, &error);
+       mono_error_set_pending_exception (&error);
+       return res;
 }
 
 /* System.TypeCode */
@@ -3790,29 +3805,29 @@ enum {
 };
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
 {
        MonoError error;
-       MonoDomain *domain; 
        MonoClass *startklass, *klass;
        int match;
        gpointer iter;
-       char *utf8_name = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;    
        MonoClassField *field;
 
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
                return g_ptr_array_new ();
        }
 
+       mono_error_init (&error);
+
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
        klass = startklass = mono_class_from_mono_type (type->type);
 
        GPtrArray *ptr_array = g_ptr_array_sized_new (16);
        
 handle_parent: 
        if (mono_class_has_failure (klass)) {
-               mono_error_init (&error);
                mono_error_set_for_class_failure (&error, klass);
                goto fail;
        }
@@ -3846,29 +3861,18 @@ handle_parent:
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (utf8_name == NULL) {
-                               utf8_name = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto fail;
-                               compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-                       }
-
-                       if (compare_func (mono_field_get_name (field), utf8_name))
+               if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
                                continue;
-               }
 
                g_ptr_array_add (ptr_array, field);
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
 
-       if (utf8_name != NULL)
-               g_free (utf8_name);
        return ptr_array;
 
 fail:
-       g_ptr_array_free (ptr_array, FALSE);
+       g_ptr_array_free (ptr_array, TRUE);
        mono_error_set_pending_exception (&error);
        return NULL;
 }
@@ -3998,28 +4002,18 @@ loader_error:
 }
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
+ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
 {
        MonoError error;
-       MonoDomain *domain; 
-       const char *mname = NULL;
        GPtrArray *method_array;
        MonoClass *klass;
 
        klass = mono_class_from_mono_type (type->type);
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
                return g_ptr_array_new ();
        }
 
-       if (name) {
-               mname = mono_string_to_utf8_checked (name, &error);
-               if (mono_error_set_pending_exception (&error))
-                   return NULL;
-       }
-
        method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
-       g_free ((char*)mname);
        mono_error_set_pending_exception (&error);
        return method_array;
 }
@@ -4146,7 +4140,7 @@ property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
 }
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
+ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
 {
        MonoError error;
        MonoClass *startklass, *klass;
@@ -4154,7 +4148,6 @@ ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, Mono
        MonoProperty *prop;
        int match;
        guint32 flags;
-       gchar *propname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        gpointer iter;
        GHashTable *properties = NULL;
@@ -4168,12 +4161,7 @@ ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, Mono
        
        klass = startklass = mono_class_from_mono_type (type->type);
 
-       if (name != NULL) {
-               propname = mono_string_to_utf8_checked (name, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return NULL;
-               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
-       }
+       compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
 
        res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
 
@@ -4181,8 +4169,10 @@ ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, Mono
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass))
+       if (mono_class_has_failure (klass)) {
+               mono_error_set_for_class_failure (&error, klass);
                goto loader_error;
+       }
 
        iter = NULL;
        while ((prop = mono_class_get_properties (klass, &iter))) {
@@ -4220,10 +4210,8 @@ handle_parent:
                        continue;
                match = 0;
 
-               if (name != NULL) {
-                       if (compare_func (propname, prop->name))
-                               continue;
-               }
+               if (propname != NULL && compare_func (propname, prop->name))
+                       continue;
                
                if (g_hash_table_lookup (properties, prop))
                        continue;
@@ -4236,20 +4224,14 @@ handle_parent:
                goto handle_parent;
 
        g_hash_table_destroy (properties);
-       g_free (propname);
 
        return res_array;
 
 
 loader_error:
-       if (mono_class_has_failure (klass))
-               mono_error_set_for_class_failure (&error, klass);
-
        if (properties)
                g_hash_table_destroy (properties);
-       if (name)
-               g_free (propname);
-       g_ptr_array_free (res_array, FALSE);
+       g_ptr_array_free (res_array, TRUE);
 
        mono_error_set_pending_exception (&error);
 
@@ -4272,7 +4254,7 @@ event_equal (MonoEvent *event1, MonoEvent *event2)
 }
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
 {
        MonoError error;
        MonoClass *startklass, *klass;
@@ -4280,7 +4262,6 @@ ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *na
        MonoEvent *event;
        int match;
        gpointer iter;
-       char *utf8_name = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;    
        GHashTable *events = NULL;
        GPtrArray *res_array;
@@ -4291,6 +4272,8 @@ ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *na
 
        mono_error_init (&error);
 
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
        res_array = g_ptr_array_sized_new (4);
 
        klass = startklass = mono_class_from_mono_type (type->type);
@@ -4299,8 +4282,10 @@ ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *na
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass))
-               goto loader_error;
+       if (mono_class_has_failure (klass)) {
+               mono_error_set_for_class_failure (&error, klass);
+               goto failure;
+       }
 
        iter = NULL;
        while ((event = mono_class_get_events (klass, &iter))) {
@@ -4341,17 +4326,8 @@ handle_parent:
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (utf8_name == NULL) {
-                               utf8_name = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto failure;
-                               compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-                       }
-
-                       if (compare_func (event->name, utf8_name))
-                               continue;
-               }               
+               if (utf8_name != NULL && compare_func (event->name, utf8_name))
+                       continue;
 
                if (g_hash_table_lookup (events, event))
                        continue;
@@ -4365,50 +4341,31 @@ handle_parent:
 
        g_hash_table_destroy (events);
 
-       if (utf8_name != NULL)
-               g_free (utf8_name);
-
        return res_array;
 
-loader_error:
-       if (mono_class_has_failure (klass))
-               mono_error_set_for_class_failure (&error, klass);
-
 failure:
-       
        if (events != NULL)
                g_hash_table_destroy (events);
-       if (utf8_name != NULL)
-               g_free (utf8_name);
 
-       g_ptr_array_free (res_array, FALSE);
+       g_ptr_array_free (res_array, TRUE);
 
        mono_error_set_pending_exception (&error);
        return NULL;
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ICALL_EXPORT GPtrArray *
+ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
 {
-       MonoError error;
-       MonoReflectionType *rt;
-       MonoDomain *domain; 
        MonoClass *klass;
-       MonoArray *res = NULL;
-       int i, match;
+       int match;
        MonoClass *nested;
        gpointer iter;
-       char *str = NULL;
-       MonoPtrArray tmp_array;
-
-       mono_error_init (&error);
+       GPtrArray *res_array;
 
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
-               MonoArray *result = mono_array_new_cached (domain, mono_defaults.runtimetype_class, 0, &error);
-               mono_error_set_pending_exception (&error);
-               return result;
+               return g_ptr_array_new ();
        }
+
        klass = mono_class_from_mono_type (type->type);
 
        /*
@@ -4423,7 +4380,8 @@ ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
 
-       mono_ptr_array_init (tmp_array, 1, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection nested types list");
+       res_array = g_ptr_array_new ();
+       
        iter = NULL;
        while ((nested = mono_class_get_nested_types (klass, &iter))) {
                match = 0;
@@ -4437,39 +4395,13 @@ ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (str == NULL) {
-                               str = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto leave;
-                               mono_identifier_unescape_type_name_chars (str);
-                       }
-
-                       if (strcmp (nested->name, str))
+               if (str != NULL && strcmp (nested->name, str))
                                continue;
-               }
-
-               rt = mono_type_get_object_checked (domain, &nested->byval_arg, &error);
-               if (!is_ok (&error))
-                       goto leave;
 
-               mono_ptr_array_append (tmp_array, (MonoObject*) rt);
+               g_ptr_array_add (res_array, &nested->byval_arg);
        }
 
-       res = mono_array_new_cached (domain, mono_defaults.runtimetype_class, mono_ptr_array_size (tmp_array), &error);
-       if (!is_ok (&error))
-               goto leave;
-
-       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
-               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
-leave:
-       mono_ptr_array_destroy (tmp_array);
-
-       g_free (str);
-
-       mono_error_set_pending_exception (&error);
-       return res;
+       return res_array;
 }
 
 ICALL_EXPORT MonoReflectionType*
@@ -5555,29 +5487,10 @@ ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assem
        return res;
 }
 
-ICALL_EXPORT void
-ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
+ICALL_EXPORT MonoAssemblyName *
+ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
 {
-       MonoError error;
-       gchar *absolute, *dirname;
-       MonoAssembly *mass = assembly->assembly;
-
-       /* XXX this is duplicated code to compute the codebase URI, unify it */
-       if (g_path_is_absolute (mass->image->name)) {
-               absolute = g_strdup (mass->image->name);
-               dirname = g_path_get_dirname (absolute);
-       } else {
-               absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
-               dirname = g_strdup (mass->basedir);
-       }
-
-       replace_shadow_path (mono_object_domain (assembly), dirname, &absolute);
-       g_free (dirname);
-
-       fill_reflection_assembly_name (mono_object_domain (assembly), aname, &mass->aname, absolute, TRUE, TRUE, TRUE, &error);
-       mono_error_set_pending_exception (&error);
-
-       g_free (absolute);
+       return &mass->aname;
 }
 
 ICALL_EXPORT void
@@ -5843,35 +5756,18 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
        return res;
 }
 
-ICALL_EXPORT gboolean
-ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
+ICALL_EXPORT void
+ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname)
 {
-       MonoError error;
-       MonoAssemblyName aname;
-       MonoDomain *domain = mono_object_domain (name);
-       char *val;
-       gboolean is_version_defined;
-       gboolean is_token_defined;
-
-       aname.public_key = NULL;
-       val = mono_string_to_utf8_checked (assname, &error);
-       if (mono_error_set_pending_exception (&error))
-               return FALSE;
-
-       if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined)) {
-               g_free ((guint8*) aname.public_key);
-               g_free (val);
-               return FALSE;
-       }
-       
-       fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined, FALSE, is_token_defined, &error);
-       mono_error_set_pending_exception (&error);
+       mono_assembly_name_free (aname);
+}
 
-       mono_assembly_name_free (&aname);
-       g_free ((guint8*) aname.public_key);
-       g_free (val);
+ICALL_EXPORT gboolean
+ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
+{
+       *is_version_definited = *is_token_defined = FALSE;
 
-       return TRUE;
+       return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
 }
 
 ICALL_EXPORT MonoReflectionType*
index b88b20e03819cb0383c8b5af48622205cd8f7524..b139ce9f3e6ef944249972c2acff47bc8d3bf4c7 100644 (file)
@@ -459,23 +459,25 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
                write_sleb128 (lne->il_offset, ptr, &ptr);
                write_sleb128 (lne->native_offset, ptr, &ptr);
        }
-
-       *ptr++ = jit->this_var ? 1 : 0;
-       if (jit->this_var)
-               write_variable (jit->this_var, ptr, &ptr);
-
-       write_leb128 (jit->num_params, ptr, &ptr);
-       for (i = 0; i < jit->num_params; i++)
-               write_variable (&jit->params [i], ptr, &ptr);
-
-       write_leb128 (jit->num_locals, ptr, &ptr);
-       for (i = 0; i < jit->num_locals; i++)
-               write_variable (&jit->locals [i], ptr, &ptr);
-
-       *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
-       if (jit->gsharedvt_info_var) {
-               write_variable (jit->gsharedvt_info_var, ptr, &ptr);
-               write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
+       write_leb128 (jit->has_var_info, ptr, &ptr);
+       if (jit->has_var_info) {
+               *ptr++ = jit->this_var ? 1 : 0;
+               if (jit->this_var)
+                       write_variable (jit->this_var, ptr, &ptr);
+
+               write_leb128 (jit->num_params, ptr, &ptr);
+               for (i = 0; i < jit->num_params; i++)
+                       write_variable (&jit->params [i], ptr, &ptr);
+
+               write_leb128 (jit->num_locals, ptr, &ptr);
+               for (i = 0; i < jit->num_locals; i++)
+                       write_variable (&jit->locals [i], ptr, &ptr);
+
+               *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
+               if (jit->gsharedvt_info_var) {
+                       write_variable (jit->gsharedvt_info_var, ptr, &ptr);
+                       write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
+               }
        }
 
        size = ptr - oldptr;
@@ -623,27 +625,29 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
                lne->il_offset = read_sleb128 (ptr, &ptr);
                lne->native_offset = read_sleb128 (ptr, &ptr);
        }
+       jit->has_var_info = read_leb128 (ptr, &ptr);
+       if (jit->has_var_info) {
+               if (*ptr++) {
+                       jit->this_var = g_new0 (MonoDebugVarInfo, 1);
+                       read_variable (jit->this_var, ptr, &ptr);
+               }
 
-       if (*ptr++) {
-               jit->this_var = g_new0 (MonoDebugVarInfo, 1);
-               read_variable (jit->this_var, ptr, &ptr);
-       }
-
-       jit->num_params = read_leb128 (ptr, &ptr);
-       jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
-       for (i = 0; i < jit->num_params; i++)
-               read_variable (&jit->params [i], ptr, &ptr);
-
-       jit->num_locals = read_leb128 (ptr, &ptr);
-       jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
-       for (i = 0; i < jit->num_locals; i++)
-               read_variable (&jit->locals [i], ptr, &ptr);
-
-       if (*ptr++) {
-               jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
-               jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
-               read_variable (jit->gsharedvt_info_var, ptr, &ptr);
-               read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
+               jit->num_params = read_leb128 (ptr, &ptr);
+               jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
+               for (i = 0; i < jit->num_params; i++)
+                       read_variable (&jit->params [i], ptr, &ptr);
+
+               jit->num_locals = read_leb128 (ptr, &ptr);
+               jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
+               for (i = 0; i < jit->num_locals; i++)
+                       read_variable (&jit->locals [i], ptr, &ptr);
+
+               if (*ptr++) {
+                       jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
+                       jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
+                       read_variable (jit->gsharedvt_info_var, ptr, &ptr);
+                       read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
+               }
        }
 
        return jit;
index 8885e521bad3c652038b49d6492af7fa42f8f9f4..c9350a7023aa2beeb12ea22ff32d4a6501c23c98 100644 (file)
@@ -86,6 +86,7 @@ struct _MonoDebugMethodJitInfo {
        const mono_byte *wrapper_addr;
        uint32_t num_line_numbers;
        MonoDebugLineNumberEntry *line_numbers;
+       uint32_t has_var_info;
        uint32_t num_params;
        MonoDebugVarInfo *this_var;
        MonoDebugVarInfo *params;
index f987e6c34837248b7368e0e19dda783615a0a3bd..c1a531c0dc87eac782c46785a481b82df532abc6 100644 (file)
@@ -364,6 +364,11 @@ mono_gc_clear_domain (MonoDomain *domain)
 {
 }
 
+void
+mono_gc_suspend_finalizers (void)
+{
+}
+
 int
 mono_gc_get_suspend_signal (void)
 {
index a6e5ab526995458a00bcb978b4ec7f08543b4431..9ce52a3515ab6bb6e9e700d24a8f6fa70b31642c 100644 (file)
@@ -1462,9 +1462,6 @@ mono_load_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mono
 gboolean
 mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, void* val, MonoError *error);
 
-void
-mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg);
-
 gboolean
 mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg, MonoError *error);
 
index 5abeed72821c95d91b536b504d0dab39dad94c8f..7bb2b43beaf795a85ecf1bcd9c94fb7804a30c98 100644 (file)
@@ -8288,65 +8288,24 @@ mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoCla
        
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoMethod *setter = NULL;
+       mono_error_init (error);
 
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc;
        MonoObject *arg;
-       char* full_name;
-
-       mono_error_init (error);
 
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);
 
-       if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
-               if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, val);
-               else mono_field_set_value (tp->rp->unwrapped_server, field, *((MonoObject **)val));
-               return TRUE;
-       }
-
-       if (!setter) {
-               setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter) {
-                       mono_error_set_not_supported (error, "Linked away.");
-                       return FALSE;
-               }
-       }
-
        if (field_class->valuetype) {
                arg = mono_value_box_checked (domain, field_class, val, error);
                return_val_if_nok (error, FALSE);
-       } else 
-               arg = *((MonoObject **)val);
-               
-
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
-       return_val_if_nok (error, FALSE);
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error);
-       return_val_if_nok (error, FALSE);
-       mono_message_init (domain, msg, rm, NULL, error);
-       return_val_if_nok (error, FALSE);
-
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       mono_array_setref (msg->args, 2, arg);
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, FALSE);
-
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return FALSE;
+       } else {
+               arg = *((MonoObject**)val);
        }
-       return TRUE;
+
+       return mono_store_remote_field_new_checked (this_obj, klass, field, arg, error);
 }
 
 /**
@@ -8366,23 +8325,6 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        mono_error_cleanup (&error);
 }
 
-/**
- * mono_store_remote_field_new_icall:
- * @this_obj:
- * @klass:
- * @field:
- * @arg:
- *
- * Missing documentation
- */
-void
-mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
-{
-       MonoError error;
-       (void) mono_store_remote_field_new_checked (this_obj, klass, field, arg, &error);
-       mono_error_set_pending_exception (&error);
-}
-
 /**
  * mono_store_remote_field_new_checked:
  * @this_obj:
@@ -8398,56 +8340,27 @@ mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mon
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoMethod *setter = NULL;
-       MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
-       MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc;
-       char* full_name;
+       static MonoMethod *tp_store = NULL;
 
        mono_error_init (error);
 
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
-       field_class = mono_class_from_mono_type (field->type);
-
-       if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
-               if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, ((gchar *) arg) + sizeof (MonoObject));
-               else mono_field_set_value (tp->rp->unwrapped_server, field, arg);
-               return TRUE;
-       }
-
-       if (!setter) {
-               setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter) {
+       if (!tp_store) {
+               tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1);
+               if (!tp_store) {
                        mono_error_set_not_supported (error, "Linked away.");
                        return FALSE;
                }
        }
 
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
-       return_val_if_nok (error, FALSE);
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error);
-       return_val_if_nok (error, FALSE);
-       mono_message_init (domain, msg, rm, NULL, error);
-       return_val_if_nok (error, FALSE);
-
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       mono_array_setref (msg->args, 2, arg);
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, FALSE);
+       gpointer args[3];
+       args [0] = &klass;
+       args [1] = &field;
+       args [2] = arg;
 
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return FALSE;
-       }
-       return TRUE;
+       mono_runtime_invoke_checked (tp_store, this_obj, args, error);
+       return is_ok (error);
 }
 #endif
 
index 62379f245e97f296a16b4a72a252c86bf7d79a84..30595ee5410e1a43cf886966b5e7175899ccf2ff 100644 (file)
@@ -198,7 +198,6 @@ mono_remoting_marshal_init (void)
                register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE);
                register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE);
                register_icall (mono_compile_method_icall, "mono_compile_method_icall", "ptr ptr", FALSE);
-               /* mono_store_remote_field_new_icall registered  by mini-runtime.c */
 
        }
 
@@ -1619,73 +1618,6 @@ mono_marshal_get_ldflda_wrapper (MonoType *type)
        return res;
 }
 
-/*
- * mono_marshal_get_stfld_remote_wrapper:
- * klass: The type of the field
- *
- *  This function generates a wrapper for calling mono_store_remote_field_new
- * with the appropriate signature.
- * Similarly to mono_marshal_get_ldfld_remote_wrapper () this doesn't depend on the
- * klass argument anymore.
- */
-MonoMethod *
-mono_marshal_get_stfld_remote_wrapper (MonoClass *klass)
-{
-       MonoMethodSignature *sig;
-       MonoMethodBuilder *mb;
-       MonoMethod *res;
-       static MonoMethod *cached = NULL;
-
-       mono_marshal_lock_internal ();
-       if (cached) {
-               mono_marshal_unlock_internal ();
-               return cached;
-       }
-       mono_marshal_unlock_internal ();
-
-       mb = mono_mb_new_no_dup_name (mono_defaults.object_class, "__mono_store_remote_field_new_wrapper", MONO_WRAPPER_STFLD_REMOTE);
-
-       mb->method->save_lmf = 1;
-
-       sig = mono_metadata_signature_alloc (mono_defaults.corlib, 4);
-       sig->params [0] = &mono_defaults.object_class->byval_arg;
-       sig->params [1] = &mono_defaults.int_class->byval_arg;
-       sig->params [2] = &mono_defaults.int_class->byval_arg;
-       sig->params [3] = &mono_defaults.object_class->byval_arg;
-       sig->ret = &mono_defaults.void_class->byval_arg;
-
-#ifndef DISABLE_JIT
-       mono_mb_emit_ldarg (mb, 0);
-       mono_mb_emit_ldarg (mb, 1);
-       mono_mb_emit_ldarg (mb, 2);
-       mono_mb_emit_ldarg (mb, 3);
-
-       mono_mb_emit_icall (mb, mono_store_remote_field_new_icall);
-
-       mono_mb_emit_byte (mb, CEE_RET);
-#endif
-
-       mono_marshal_lock_internal ();
-       res = cached;
-       mono_marshal_unlock_internal ();
-       if (!res) {
-               MonoMethod *newm;
-               newm = mono_mb_create (mb, sig, 6, NULL);
-               mono_marshal_lock_internal ();
-               res = cached;
-               if (!res) {
-                       res = newm;
-                       cached = res;
-                       mono_marshal_unlock_internal ();
-               } else {
-                       mono_marshal_unlock_internal ();
-                       mono_free_method (newm);
-               }
-       }
-       mono_mb_free (mb);
-       
-       return res;
-}
 
 /*
  * mono_marshal_get_stfld_wrapper:
@@ -1706,6 +1638,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        WrapperInfo *info;
        char *name;
        int t, pos;
+       static MonoMethod *tp_store = NULL;
 
        type = mono_type_get_underlying_type (type);
        t = type->type;
@@ -1735,6 +1668,13 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        if ((res = mono_marshal_find_in_cache (cache, klass)))
                return res;
 
+#ifndef DISABLE_REMOTING
+       if (!tp_store) {
+               tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1);
+               g_assert (tp_store != NULL);
+       }
+#endif
+
        /* we add the %p pointer value of klass because class names are not unique */
        name = g_strdup_printf ("__stfld_wrapper_%p_%s.%s", klass, klass->name_space, klass->name); 
        mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_STFLD);
@@ -1752,6 +1692,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        mono_mb_emit_ldarg (mb, 0);
        pos = mono_mb_emit_proxy_check (mb, CEE_BNE_UN);
 
+#ifndef DISABLE_REMOTING
        mono_mb_emit_ldarg (mb, 0);
        mono_mb_emit_ldarg (mb, 1);
        mono_mb_emit_ldarg (mb, 2);
@@ -1759,9 +1700,10 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        if (klass->valuetype)
                mono_mb_emit_op (mb, CEE_BOX, klass);
 
-       mono_mb_emit_managed_call (mb, mono_marshal_get_stfld_remote_wrapper (klass), NULL);
+       mono_mb_emit_managed_call (mb, tp_store, NULL);
 
        mono_mb_emit_byte (mb, CEE_RET);
+#endif
 
        mono_mb_patch_branch (mb, pos);
 
index 9b495b2fb59f87be44d473aad0f80691a09af3ad..b0307aed93dfe044247ac64fee04393385b97eca 100644 (file)
@@ -38,12 +38,6 @@ mono_marshal_get_ldfld_wrapper (MonoType *type);
 MonoMethod *
 mono_marshal_get_ldflda_wrapper (MonoType *type);
 
-MonoMethod *
-mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass);
-
-MonoMethod *
-mono_marshal_get_stfld_remote_wrapper (MonoClass *klass);
-
 MonoMethod *
 mono_marshal_get_proxy_cancast (MonoClass *klass);
 
index 247818656b5d2d502fc0e88f08ab0ed867b17435..33e01a8fb28717c98abc9e1f0a1978f156a81676 100644 (file)
@@ -140,7 +140,8 @@ mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
 
        HEAVY_STAT (++stat_wbarrier_object_copy);
 
-       if (sgen_ptr_in_nursery (obj) || ptr_on_stack (obj) || !SGEN_OBJECT_HAS_REFERENCES (src)) {
+       SGEN_ASSERT (6, !ptr_on_stack (obj), "Why is this called for a non-reference type?");
+       if (sgen_ptr_in_nursery (obj) || !SGEN_OBJECT_HAS_REFERENCES (src)) {
                size = mono_object_class (obj)->instance_size;
                mono_gc_memmove_aligned ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
                                size - sizeof (MonoObject));
@@ -529,9 +530,15 @@ object_in_domain_predicate (MonoObject *obj, void *user_data)
  * @suspend is used for early termination of the enqueuing process.
  */
 void
-mono_gc_finalize_domain (MonoDomain *domain, volatile gboolean *suspend)
+mono_gc_finalize_domain (MonoDomain *domain)
 {
-       sgen_finalize_if (object_in_domain_predicate, domain, suspend);
+       sgen_finalize_if (object_in_domain_predicate, domain);
+}
+
+void
+mono_gc_suspend_finalizers (void)
+{
+       sgen_set_suspend_finalizers ();
 }
 
 /*
index 87c976b48739179b813cc7a1364e23d7745df73e..c15d5be8ad134fdac250e1280362368eb263f58e 100644 (file)
@@ -635,6 +635,9 @@ worker_thread (gpointer data)
                        if (retire)
                                retire = FALSE;
 
+                       /* The tpdomain->domain might have unloaded, while this thread was parked */
+                       previous_tpdomain = NULL;
+
                        continue;
                }
 
index 50a4329603c88dd60e2ad06a1e78e1a2334ad7f4..523b5188cc5a5edb22fae1514edec68a6a49b79d 100644 (file)
@@ -745,7 +745,14 @@ static guint32 WINAPI start_wrapper_internal(void *data)
                args [0] = start_arg;
                /* we may want to handle the exception here. See comment below on unhandled exceptions */
                mono_runtime_delegate_invoke_checked (start_delegate, args, &error);
-               mono_error_raise_exception (&error); /* OK, triggers unhandled exn handler */
+
+               if (!mono_error_ok (&error)) {
+                       MonoException *ex = mono_error_convert_to_exception (&error);
+                       if (ex)
+                               mono_unhandled_exception (&ex->object);
+               } else {
+                       mono_error_cleanup (&error);
+               }
        }
 
        /* If the thread calls ExitThread at all, this remaining code
@@ -3157,7 +3164,7 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
                wait->num++;
 
                THREAD_DEBUG (g_print ("%s: Aborting id: %"G_GSIZE_FORMAT"\n", __func__, (gsize)thread->tid));
-               mono_thread_internal_stop (thread);
+               mono_thread_internal_abort (thread);
                return TRUE;
        }
 
index 909113cae8e97077451a2dedf70dea6fbf87b99f..fc2c8954426a32bdba980bdc7f203c66bb8bc205 100644 (file)
@@ -17,7 +17,6 @@ WRAPPER(XDOMAIN_INVOKE, "xdomain-invoke")
 WRAPPER(XDOMAIN_DISPATCH, "xdomain-dispatch")
 WRAPPER(LDFLD, "ldfld")
 WRAPPER(STFLD, "stfld")
-WRAPPER(STFLD_REMOTE, "stfld-remote")
 WRAPPER(SYNCHRONIZED, "synchronized")
 WRAPPER(DYNAMIC_METHOD, "dynamic-method")
 WRAPPER(ISINST, "isinst")
index 7791ec26d0b55fbff726f895120fea3eb16e118b..5719f5f1207d158d57f30b258e1595631142d73d 100644 (file)
@@ -3104,8 +3104,6 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8
                        encode_klass_ref (acfg, info->d.proxy.klass, p, &p);
                        break;
                }
-               case MONO_WRAPPER_STFLD_REMOTE:
-                       break;
                case MONO_WRAPPER_ALLOC: {
                        /* The GC name is saved once in MonoAotFileInfo */
                        g_assert (info->d.alloc.alloc_type != -1);
@@ -7209,7 +7207,6 @@ can_encode_method (MonoAotCompile *acfg, MonoMethod *method)
                        case MONO_WRAPPER_STFLD:
                        case MONO_WRAPPER_LDFLD:
                        case MONO_WRAPPER_LDFLDA:
-                       case MONO_WRAPPER_STFLD_REMOTE:
                        case MONO_WRAPPER_STELEMREF:
                        case MONO_WRAPPER_ISINST:
                        case MONO_WRAPPER_PROXY_ISINST:
index 14fcfbabc056fbde074805348a4d92c75fdb1133..2f818c6821cef511e12f349739f013f8de8e7116 100644 (file)
@@ -922,9 +922,6 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        }
                        break;
                }
-               case MONO_WRAPPER_STFLD_REMOTE:
-                       ref->method = mono_marshal_get_stfld_remote_wrapper (NULL);
-                       break;
 #endif
                case MONO_WRAPPER_ALLOC: {
                        int atype = decode_value (p, &p);
index 2ef1c93fd5622f3d085f4457decf9523038b0664..41e241a33a8bf1a14ee1b64f4f07f5773fac4a0e 100644 (file)
@@ -240,29 +240,32 @@ mono_debug_close_method (MonoCompile *cfg)
        jit->code_start = cfg->native_code;
        jit->epilogue_begin = cfg->epilog_begin;
        jit->code_size = cfg->code_len;
+       jit->has_var_info = debug_options.mdb_optimizations != 0;
 
        if (jit->epilogue_begin)
                   record_line_number (info, jit->epilogue_begin, header->code_size);
 
-       jit->num_params = sig->param_count;
-       jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
+       if (jit->has_var_info) {
+               jit->num_params = sig->param_count;
+               jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
 
-       for (i = 0; i < jit->num_locals; i++)
-               write_variable (cfg->locals [i], &jit->locals [i]);
+               for (i = 0; i < jit->num_locals; i++)
+                       write_variable (cfg->locals [i], &jit->locals [i]);
 
-       if (sig->hasthis) {
-               jit->this_var = g_new0 (MonoDebugVarInfo, 1);
-               write_variable (cfg->args [0], jit->this_var);
-       }
+               if (sig->hasthis) {
+                       jit->this_var = g_new0 (MonoDebugVarInfo, 1);
+                       write_variable (cfg->args [0], jit->this_var);
+               }
 
-       for (i = 0; i < jit->num_params; i++)
-               write_variable (cfg->args [i + sig->hasthis], &jit->params [i]);
+               for (i = 0; i < jit->num_params; i++)
+                       write_variable (cfg->args [i + sig->hasthis], &jit->params [i]);
 
-       if (cfg->gsharedvt_info_var) {
-               jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
-               jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
-               write_variable (cfg->gsharedvt_info_var, jit->gsharedvt_info_var);
-               write_variable (cfg->gsharedvt_locals_var, jit->gsharedvt_locals_var);
+               if (cfg->gsharedvt_info_var) {
+                       jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
+                       jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
+                       write_variable (cfg->gsharedvt_info_var, jit->gsharedvt_info_var);
+                       write_variable (cfg->gsharedvt_locals_var, jit->gsharedvt_locals_var);
+               }
        }
 
        jit->num_line_numbers = info->line_numbers->len;
@@ -457,22 +460,25 @@ mono_debug_serialize_debug_info (MonoCompile *cfg, guint8 **out_buf, guint32 *bu
        encode_value (jit->epilogue_begin, p, &p);
        encode_value (jit->prologue_end, p, &p);
        encode_value (jit->code_size, p, &p);
+       encode_value (jit->has_var_info, p, &p);
 
-       for (i = 0; i < jit->num_params; ++i)
-               serialize_variable (&jit->params [i], p, &p);
+       if (jit->has_var_info) {
+               for (i = 0; i < jit->num_params; ++i)
+                       serialize_variable (&jit->params [i], p, &p);
 
-       if (mono_method_signature (cfg->method)->hasthis)
-               serialize_variable (jit->this_var, p, &p);
+               if (jit->this_var)
+                       serialize_variable (jit->this_var, p, &p);
 
-       for (i = 0; i < jit->num_locals; i++)
-               serialize_variable (&jit->locals [i], p, &p);
+               for (i = 0; i < jit->num_locals; i++)
+                       serialize_variable (&jit->locals [i], p, &p);
 
-       if (jit->gsharedvt_info_var) {
-               encode_value (1, p, &p);
-               serialize_variable (jit->gsharedvt_info_var, p, &p);
-               serialize_variable (jit->gsharedvt_locals_var, p, &p);
-       } else {
-               encode_value (0, p, &p);
+               if (jit->gsharedvt_info_var) {
+                       encode_value (1, p, &p);
+                       serialize_variable (jit->gsharedvt_info_var, p, &p);
+                       serialize_variable (jit->gsharedvt_locals_var, p, &p);
+               } else {
+                       encode_value (0, p, &p);
+               }
        }
 
        encode_value (jit->num_line_numbers, p, &p);
@@ -535,32 +541,36 @@ deserialize_debug_info (MonoMethod *method, guint8 *code_start, guint8 *buf, gui
 
        jit = g_new0 (MonoDebugMethodJitInfo, 1);
        jit->code_start = code_start;
-       jit->num_locals = header->num_locals;
-       jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
-       jit->num_params = mono_method_signature (method)->param_count;
-       jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
 
        p = buf;
        jit->epilogue_begin = decode_value (p, &p);
        jit->prologue_end = decode_value (p, &p);
        jit->code_size = decode_value (p, &p);
+       jit->has_var_info = decode_value (p, &p);
 
-       for (i = 0; i < jit->num_params; ++i)
-               deserialize_variable (&jit->params [i], p, &p);
+       if (jit->has_var_info) {
+               jit->num_locals = header->num_locals;
+               jit->num_params = mono_method_signature (method)->param_count;
+               jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
+               jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
 
-       if (mono_method_signature (method)->hasthis) {
-               jit->this_var = g_new0 (MonoDebugVarInfo, 1);
-               deserialize_variable (jit->this_var, p, &p);
-       }
+               for (i = 0; i < jit->num_params; ++i)
+                       deserialize_variable (&jit->params [i], p, &p);
 
-       for (i = 0; i < jit->num_locals; i++)
-               deserialize_variable (&jit->locals [i], p, &p);
+               if (mono_method_signature (method)->hasthis) {
+                       jit->this_var = g_new0 (MonoDebugVarInfo, 1);
+                       deserialize_variable (jit->this_var, p, &p);
+               }
+
+               for (i = 0; i < jit->num_locals; i++)
+                       deserialize_variable (&jit->locals [i], p, &p);
 
-       if (decode_value (p, &p)) {
-               jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
-               jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
-               deserialize_variable (jit->gsharedvt_info_var, p, &p);
-               deserialize_variable (jit->gsharedvt_locals_var, p, &p);
+               if (decode_value (p, &p)) {
+                       jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
+                       jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
+                       deserialize_variable (jit->gsharedvt_info_var, p, &p);
+                       deserialize_variable (jit->gsharedvt_locals_var, p, &p);
+               }
        }
 
        jit->num_line_numbers = decode_value (p, &p);
index 9b569ffc9c72fa8ca23ff029f10199efeb9745cd..c84da624146e3fa8d14c8ba5758fd49301595972 100644 (file)
@@ -2790,8 +2790,6 @@ suspend_vm (void)
 static void
 resume_vm (void)
 {
-       int err;
-
        g_assert (is_debugger_thread ());
 
        mono_loader_lock ();
@@ -2810,8 +2808,7 @@ resume_vm (void)
        }
 
        /* Signal this even when suspend_count > 0, since some threads might have resume_count > 0 */
-       err = mono_coop_cond_broadcast (&suspend_cond);
-       g_assert (err == 0);
+       mono_coop_cond_broadcast (&suspend_cond);
 
        mono_coop_mutex_unlock (&suspend_mutex);
        //g_assert (err == 0);
@@ -2830,7 +2827,6 @@ resume_vm (void)
 static void
 resume_thread (MonoInternalThread *thread)
 {
-       int err;
        DebuggerTlsData *tls;
 
        g_assert (is_debugger_thread ());
@@ -2852,8 +2848,7 @@ resume_thread (MonoInternalThread *thread)
         * Signal suspend_count without decreasing suspend_count, the threads will wake up
         * but only the one whose resume_count field is > 0 will be resumed.
         */
-       err = mono_coop_cond_broadcast (&suspend_cond);
-       g_assert (err == 0);
+       mono_coop_cond_broadcast (&suspend_cond);
 
        mono_coop_mutex_unlock (&suspend_mutex);
        //g_assert (err == 0);
@@ -2900,7 +2895,6 @@ static void
 suspend_current (void)
 {
        DebuggerTlsData *tls;
-       int err;
 
        g_assert (!is_debugger_thread ());
 
@@ -2928,8 +2922,7 @@ suspend_current (void)
        DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer) (gsize) mono_native_thread_id_get ());
 
        while (suspend_count - tls->resume_count > 0) {
-               err = mono_coop_cond_wait (&suspend_cond, &suspend_mutex);
-               g_assert (err == 0);
+               mono_coop_cond_wait (&suspend_cond, &suspend_mutex);
        }
 
        tls->suspended = FALSE;
@@ -4335,6 +4328,7 @@ set_bp_in_method (MonoDomain *domain, MonoMethod *method, MonoSeqPointInfo *seq_
                MonoError oerror;
 
                /* Might be AOTed code */
+               mono_class_init (method->klass);
                code = mono_aot_get_method_checked (domain, method, &oerror);
                g_assert (code);
                mono_error_assert_ok (&oerror);
@@ -9149,7 +9143,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
        sig = mono_method_signature (frame->actual_method);
 
-       if (!mono_get_seq_points (frame->domain, frame->actual_method))
+       if (!jit->has_var_info || !mono_get_seq_points (frame->domain, frame->actual_method))
                /*
                 * The method is probably from an aot image compiled without soft-debug, variables might be dead, etc.
                 */
@@ -9467,10 +9461,10 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                g_free (val);
                        } else {
                                guint8 *field_value = NULL;
-                               void *field_storage = NULL;
 
                                if (remote_obj) {
 #ifndef DISABLE_REMOTING
+                                       void *field_storage = NULL;
                                        field_value = mono_load_remote_field_checked(obj, obj_type, f, &field_storage, &error);
                                        if (!is_ok (&error)) {
                                                mono_error_cleanup (&error); /* FIXME report the error */
index 4fbe7c06c0886c91d4418f029b016f019d6f2339..d4262ab7d2f29ce023aacec66b642392877dcf0a 100644 (file)
@@ -827,6 +827,10 @@ mono_arch_init (void)
 {
        const char *cpu_arch;
 
+#ifdef TARGET_WATCHOS
+       mini_get_debug_options ()->soft_breakpoints = TRUE;
+#endif
+
        mono_os_mutex_init_recursive (&mini_arch_mutex);
        if (mini_get_debug_options ()->soft_breakpoints) {
                breakpoint_tramp = mini_get_breakpoint_trampoline ();
@@ -880,6 +884,21 @@ mono_arch_init (void)
        v6_supported = mono_hwcap_arm_is_v6;
        v7_supported = mono_hwcap_arm_is_v7;
 
+       /*
+        * On weird devices, the hwcap code may fail to detect
+        * the ARM version. In that case, we can at least safely
+        * assume the version the runtime was compiled for.
+        */
+#ifdef HAVE_ARMV5
+       v5_supported = TRUE;
+#endif
+#ifdef HAVE_ARMV6
+       v6_supported = TRUE;
+#endif
+#ifdef HAVE_ARMV7
+       v7_supported = TRUE;
+#endif
+
 #if defined(__APPLE__)
        /* iOS is special-cased here because we don't yet
           have a way to properly detect CPU features on it. */
@@ -1883,6 +1902,9 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                ins->inst_basereg = cfg->frame_reg;
                ins->inst_offset = offset;
                offset += size;
+       }
+       if (cfg->arch.ss_trigger_page_var) {
+               MonoInst *ins;
 
                ins = cfg->arch.ss_trigger_page_var;
                size = 4;
@@ -1907,6 +1929,9 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                ins->inst_basereg = cfg->frame_reg;
                ins->inst_offset = offset;
                offset += size;
+       }
+       if (cfg->arch.seq_point_bp_method_var) {
+               MonoInst *ins;
 
                ins = cfg->arch.seq_point_bp_method_var;
                size = 4;
@@ -2087,6 +2112,18 @@ mono_arch_create_vars (MonoCompile *cfg)
        }
 
        if (cfg->gen_sdb_seq_points) {
+               if (cfg->compile_aot) {
+                       MonoInst *ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+                       ins->flags |= MONO_INST_VOLATILE;
+                       cfg->arch.seq_point_info_var = ins;
+
+                       if (!cfg->soft_breakpoints) {
+                               /* Allocate a separate variable for this to save 1 load per seq point */
+                               ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+                               ins->flags |= MONO_INST_VOLATILE;
+                               cfg->arch.ss_trigger_page_var = ins;
+                       }
+               }
                if (cfg->soft_breakpoints) {
                        MonoInst *ins;
 
@@ -2097,17 +2134,6 @@ mono_arch_create_vars (MonoCompile *cfg)
                        ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                        ins->flags |= MONO_INST_VOLATILE;
                        cfg->arch.seq_point_bp_method_var = ins;
-
-                       g_assert (!cfg->compile_aot);
-               } else if (cfg->compile_aot) {
-                       MonoInst *ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-                       ins->flags |= MONO_INST_VOLATILE;
-                       cfg->arch.seq_point_info_var = ins;
-
-                       /* Allocate a separate variable for this to save 1 load per seq point */
-                       ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-                       ins->flags |= MONO_INST_VOLATILE;
-                       cfg->arch.ss_trigger_page_var = ins;
                }
        }
 }
@@ -4575,9 +4601,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        MonoInst *var;
                        int dreg = ARMREG_LR;
 
+#if 0
                        if (cfg->soft_breakpoints) {
                                g_assert (!cfg->compile_aot);
                        }
+#endif
 
                        /*
                         * For AOT, we use one got slot per method, which will point to a
@@ -4634,20 +4662,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
 
-                       if (cfg->soft_breakpoints) {
-                               /* Load the address of the breakpoint method into ip. */
-                               var = bp_method_var;
-                               g_assert (var);
-                               g_assert (var->opcode == OP_REGOFFSET);
-                               g_assert (arm_is_imm12 (var->inst_offset));
-                               ARM_LDR_IMM (code, dreg, var->inst_basereg, var->inst_offset);
-
-                               /*
-                                * A placeholder for a possible breakpoint inserted by
-                                * mono_arch_set_breakpoint ().
-                                */
-                               ARM_NOP (code);
-                       } else if (cfg->compile_aot) {
+                       if (cfg->compile_aot) {
                                guint32 offset = code - cfg->native_code;
                                guint32 val;
 
@@ -4670,7 +4685,23 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                /* What is faster, a branch or a load ? */
                                ARM_CMP_REG_IMM (code, dreg, 0, 0);
                                /* The breakpoint instruction */
-                               ARM_LDR_IMM_COND (code, dreg, dreg, 0, ARMCOND_NE);
+                               if (cfg->soft_breakpoints)
+                                       ARM_BLX_REG_COND (code, ARMCOND_NE, dreg);
+                               else
+                                       ARM_LDR_IMM_COND (code, dreg, dreg, 0, ARMCOND_NE);
+                       } else if (cfg->soft_breakpoints) {
+                               /* Load the address of the breakpoint method into ip. */
+                               var = bp_method_var;
+                               g_assert (var);
+                               g_assert (var->opcode == OP_REGOFFSET);
+                               g_assert (arm_is_imm12 (var->inst_offset));
+                               ARM_LDR_IMM (code, dreg, var->inst_basereg, var->inst_offset);
+
+                               /*
+                                * A placeholder for a possible breakpoint inserted by
+                                * mono_arch_set_breakpoint ().
+                                */
+                               ARM_NOP (code);
                        } else {
                                /* 
                                 * A placeholder for a possible breakpoint inserted by
@@ -7169,17 +7200,16 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip)
        guint32 native_offset = ip - (guint8*)ji->code_start;
        MonoDebugOptions *opt = mini_get_debug_options ();
 
-       if (opt->soft_breakpoints) {
-               g_assert (!ji->from_aot);
-               code += 4;
-               ARM_BLX_REG (code, ARMREG_LR);
-               mono_arch_flush_icache (code - 4, 4);
-       } else if (ji->from_aot) {
+       if (ji->from_aot) {
                SeqPointInfo *info = mono_arch_get_seq_point_info (mono_domain_get (), ji->code_start);
 
                g_assert (native_offset % 4 == 0);
                g_assert (info->bp_addrs [native_offset / 4] == 0);
-               info->bp_addrs [native_offset / 4] = bp_trigger_page;
+               info->bp_addrs [native_offset / 4] = opt->soft_breakpoints ? breakpoint_tramp : bp_trigger_page;
+       } else if (opt->soft_breakpoints) {
+               code += 4;
+               ARM_BLX_REG (code, ARMREG_LR);
+               mono_arch_flush_icache (code - 4, 4);
        } else {
                int dreg = ARMREG_LR;
 
@@ -7215,18 +7245,17 @@ mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip)
        guint8 *code = ip;
        int i;
 
-       if (opt->soft_breakpoints) {
-               g_assert (!ji->from_aot);
-               code += 4;
-               ARM_NOP (code);
-               mono_arch_flush_icache (code - 4, 4);
-       } else if (ji->from_aot) {
+       if (ji->from_aot) {
                guint32 native_offset = ip - (guint8*)ji->code_start;
                SeqPointInfo *info = mono_arch_get_seq_point_info (mono_domain_get (), ji->code_start);
 
                g_assert (native_offset % 4 == 0);
-               g_assert (info->bp_addrs [native_offset / 4] == bp_trigger_page);
+               g_assert (info->bp_addrs [native_offset / 4] == (opt->soft_breakpoints ? breakpoint_tramp : bp_trigger_page));
                info->bp_addrs [native_offset / 4] = 0;
+       } else if (opt->soft_breakpoints) {
+               code += 4;
+               ARM_NOP (code);
+               mono_arch_flush_icache (code - 4, 4);
        } else {
                for (i = 0; i < 4; ++i)
                        ARM_NOP (code);
index 36225e43a5fd315cbc9d7f6aa151ae45bc26e7f1..e1918076a8a97099a952d461b43b0d7e6f9fdfad 100644 (file)
@@ -3695,9 +3695,7 @@ mini_init (const char *filename, const char *runtime_version)
        mono_simd_intrinsics_init ();
 #endif
 
-#if MONO_SUPPORT_TASKLETS
        mono_tasklets_init ();
-#endif
 
        register_trampolines (domain);
 
@@ -3778,9 +3776,6 @@ register_icalls (void)
        register_icall (mono_thread_get_undeniable_exception, "mono_thread_get_undeniable_exception", "object", FALSE);
        register_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", "object", FALSE);
        register_icall (mono_thread_force_interruption_checkpoint_noraise, "mono_thread_force_interruption_checkpoint_noraise", "object", FALSE);
-#ifndef DISABLE_REMOTING
-       register_icall (mono_store_remote_field_new_icall, "mono_store_remote_field_new_icall", "void object ptr ptr object", FALSE);
-#endif
 
 #if defined(__native_client__) || defined(__native_client_codegen__)
        register_icall (mono_nacl_gc, "mono_nacl_gc", "void", FALSE);
index 12be87a1fab52deee3d143b7202cbf665e572f47..8c1fe23297bffd8ba8b6ce8c9a6f43e62fff2b78 100644 (file)
@@ -1522,8 +1522,7 @@ mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *e
                if (code)
                        return code;
                if (mono_llvm_only) {
-                       if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST ||
-                               method->wrapper_type == MONO_WRAPPER_STFLD_REMOTE)
+                       if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST)
                                /* These wrappers are not generated */
                                return method_not_found;
                        /* Methods are lazily initialized on first call, so this can't lead recursion */
index 92671537280fefbc287bde55e987e6aa7468de70..21e8e62ad3793b8cd67db09a88a89d20f81c403a 100644 (file)
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 135
+#define MONO_AOT_FILE_VERSION 136
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
index 08deb0c00f2913bf8c8fdccf4173ec7d5e8d768f..7d035aa3b2cef9707ee18b92ba25ae687d511de8 100644 (file)
@@ -150,6 +150,57 @@ void
 mono_tasklets_cleanup (void)
 {
 }
+#else
 
+static
+void continuations_not_supported (void)
+{
+       mono_set_pending_exception (mono_get_exception_not_implemented ("Tasklets are not implemented on this platform."));
+}
+
+static void*
+continuation_alloc (void)
+{
+       continuations_not_supported ();
+       return NULL;
+}
+
+static void
+continuation_free (MonoContinuation *cont)
+{
+       continuations_not_supported ();
+}
+
+static MonoException*
+continuation_mark_frame (MonoContinuation *cont)
+{
+       continuations_not_supported ();
+       return NULL;
+}
+
+static int
+continuation_store (MonoContinuation *cont, int state, MonoException **e)
+{
+       continuations_not_supported ();
+       return 0;
+}
+
+static MonoException*
+continuation_restore (MonoContinuation *cont, int state)
+{
+       continuations_not_supported ();
+       return NULL;
+}
+
+void
+mono_tasklets_init(void)
+{
+       mono_add_internal_call ("Mono.Tasklets.Continuation::alloc", continuation_alloc);
+       mono_add_internal_call ("Mono.Tasklets.Continuation::free", continuation_free);
+       mono_add_internal_call ("Mono.Tasklets.Continuation::mark", continuation_mark_frame);
+       mono_add_internal_call ("Mono.Tasklets.Continuation::store", continuation_store);
+       mono_add_internal_call ("Mono.Tasklets.Continuation::restore", continuation_restore);
+
+}
 #endif
 
index 016fc462e0e762772ccbb9f6701eaf4c583937af..3579d09bae865777c4bb114fbc6370dd161f54df 100644 (file)
@@ -8,6 +8,27 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
+/*
+ * Defines
+ *
+ *     GCObject* copy_object_no_checks (GCObject *obj, SgenGrayQueue *queue)
+ *
+ * which allocates new space for `obj`, copies it there, forwards `obj` to its new location,
+ * and enqueues the copy into `queue`.
+ *
+ * To be defined by the includer:
+ *
+ *     COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION(vt, obj, objsize, has_refs)
+ *
+ * Allocates space for promoting object `obj`, with size `objsize`, and initizializes the
+ * vtable with `vt`.  `has_refs` indicates whether the object contains references.
+ *
+ *     collector_pin_object(obj, queue)
+ *
+ * Called when no space for `obj` could be allocated.  It must pin `obj` and enqueue it into
+ * `queue` for scanning.
+ */
+
 extern guint64 stat_copy_object_called_nursery;
 extern guint64 stat_objects_copied_nursery;
 
@@ -73,3 +94,6 @@ copy_object_no_checks (GCObject *obj, SgenGrayQueue *queue)
 
        return (GCObject *)destination;
 }
+
+#undef COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION
+#undef collector_pin_object
index 6daa9199dfcea5d7067518d98732a153cb5f6abc..f073dc740648154853db6016d8a4564f7f137fe0 100644 (file)
@@ -149,15 +149,16 @@ static gboolean missing_remsets;
  */
 #undef HANDLE_PTR
 #define HANDLE_PTR(ptr,obj)    do {    \
-       if (*(ptr) && sgen_ptr_in_nursery ((char*)*(ptr))) { \
-               if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr))) { \
-                       GCVTable __vt = SGEN_LOAD_VTABLE (obj); \
-                       SGEN_LOG (0, "Oldspace->newspace reference %p at offset %zd in object %p (%s.%s) not found in remsets.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt)); \
-                       binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \
-                       if (!object_is_pinned (*(ptr)))                                                         \
-                               missing_remsets = TRUE;                                                                 \
-               }                                                                                                                               \
-       }                                                                                                                                       \
+               if (*(ptr) && sgen_ptr_in_nursery ((char*)*(ptr))) {    \
+                       if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr))) { \
+                               GCVTable __vt = SGEN_LOAD_VTABLE (obj); \
+                               gboolean is_pinned = object_is_pinned (*(ptr)); \
+                               SGEN_LOG (0, "Oldspace->newspace reference %p at offset %zd in object %p (%s.%s) not found in remsets%s.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt), is_pinned ? ", but object is pinned" : ""); \
+                               binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), is_pinned); \
+                               if (!is_pinned)                         \
+                                       missing_remsets = TRUE;         \
+                       }                                               \
+               }                                                       \
        } while (0)
 
 /*
@@ -181,7 +182,7 @@ check_consistency_callback (GCObject *obj, size_t size, void *dummy)
  * Assumes the world is stopped.
  */
 void
-sgen_check_consistency (void)
+sgen_check_remset_consistency (void)
 {
        // Need to add more checks
 
@@ -196,6 +197,8 @@ sgen_check_consistency (void)
 
        SGEN_LOG (1, "Heap consistency check done.");
 
+       if (missing_remsets)
+               binary_protocol_flush_buffers (TRUE);
        if (!binary_protocol_is_enabled ())
                g_assert (!missing_remsets);
 }
@@ -426,15 +429,15 @@ missing_remset_spew (char *obj, char **slot)
 FIXME Flag missing remsets due to pinning as non fatal
 */
 #undef HANDLE_PTR
-#define HANDLE_PTR(ptr,obj)    do {    \
-               if (*(char**)ptr) {     \
+#define HANDLE_PTR(ptr,obj)    do {                                    \
+               if (*(char**)ptr) {                                     \
                        if (!is_valid_object_pointer (*(char**)ptr)) {  \
-                               bad_pointer_spew ((char*)obj, (char**)ptr);     \
-                       } else if (!sgen_ptr_in_nursery (obj) && sgen_ptr_in_nursery ((char*)*ptr)) {   \
-                               if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr)) && (!allow_missing_pinned || !SGEN_OBJECT_IS_PINNED (*(ptr)))) \
-                               missing_remset_spew ((char*)obj, (char**)ptr);  \
-                       }       \
-        } \
+                               bad_pointer_spew ((char*)obj, (char**)ptr); \
+                       } else if (!sgen_ptr_in_nursery (obj) && sgen_ptr_in_nursery ((char*)*ptr)) { \
+                               if (!allow_missing_pinned && !SGEN_OBJECT_IS_PINNED (*(ptr)) && !sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr))) \
+                                       missing_remset_spew ((char*)obj, (char**)ptr); \
+                       }                                               \
+               }                                                       \
        } while (0)
 
 static void
index f6cab27ec4fe5a2909833626145752e954be043d..bef8bcded6fdb1ea3440012debe30e9a21ac7996 100644 (file)
@@ -558,7 +558,7 @@ sgen_object_register_for_finalization (GCObject *obj, void *user_data)
 
 /* LOCKING: requires that the GC lock is held */
 static void
-finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, volatile gboolean *suspend, SgenHashTable *hash_table)
+finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, SgenHashTable *hash_table)
 {
        GCObject *object;
        gpointer dummy G_GNUC_UNUSED;
@@ -575,7 +575,7 @@ finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, vol
                        SGEN_LOG (5, "Enqueuing object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
                }
 
-               if (*suspend)
+               if (sgen_suspend_finalizers)
                        break;
        } SGEN_HASH_TABLE_FOREACH_END;
 }
@@ -597,12 +597,12 @@ finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, vol
  * objects are still alive.
  */
 void
-sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data, volatile gboolean *suspend)
+sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data)
 {
        LOCK_GC;
        sgen_process_fin_stage_entries ();
-       finalize_with_predicate (predicate, user_data, suspend, &minor_finalizable_hash);
-       finalize_with_predicate (predicate, user_data, suspend, &major_finalizable_hash);
+       finalize_with_predicate (predicate, user_data, &minor_finalizable_hash);
+       finalize_with_predicate (predicate, user_data, &major_finalizable_hash);
        UNLOCK_GC;
 }
 
index 3dac1df3d8dfb82cc4c835eba8d0b59c4c5ad603..7b650e42caed2aca222b783dea5788135e495edf 100644 (file)
@@ -214,8 +214,8 @@ guint32 verify_before_allocs = 0;
 guint32 collect_before_allocs = 0;
 /* If set, do a whole heap check before each collection */
 static gboolean whole_heap_check_before_collection = FALSE;
-/* If set, do a heap consistency check before each minor collection */
-static gboolean consistency_check_at_minor_collection = FALSE;
+/* If set, do a remset consistency check at various opportunities */
+static gboolean remset_consistency_checks = FALSE;
 /* If set, do a mod union consistency check before each finishing collection pause */
 static gboolean mod_union_consistency_check = FALSE;
 /* If set, check whether mark bits are consistent after major collections */
@@ -288,9 +288,6 @@ static guint64 time_max = 0;
 static SGEN_TV_DECLARE (time_major_conc_collection_start);
 static SGEN_TV_DECLARE (time_major_conc_collection_end);
 
-static SGEN_TV_DECLARE (last_minor_collection_start_tv);
-static SGEN_TV_DECLARE (last_minor_collection_end_tv);
-
 int gc_debug_level = 0;
 FILE* gc_debug_file;
 
@@ -399,8 +396,6 @@ static mword objects_pinned;
  * ######################################################################
  */
 
-typedef SgenGrayQueue GrayQueue;
-
 /* forward declarations */
 static void scan_from_registered_roots (char *addr_start, char *addr_end, int root_type, ScanCopyContext ctx);
 
@@ -410,51 +405,29 @@ static void finish_gray_stack (int generation, ScanCopyContext ctx);
 
 SgenMajorCollector major_collector;
 SgenMinorCollector sgen_minor_collector;
-/* FIXME: get rid of this */
-static GrayQueue gray_queue;
 
 static SgenRememberedSet remset;
 
-/* The gray queue to use from the main collection thread. */
-#define WORKERS_DISTRIBUTE_GRAY_QUEUE  (&gray_queue)
-
 /*
  * The gray queue a worker job must use.  If we're not parallel or
  * concurrent, we use the main gray queue.
  */
 static SgenGrayQueue*
-sgen_workers_get_job_gray_queue (WorkerData *worker_data)
-{
-       return worker_data ? &worker_data->private_gray_queue : WORKERS_DISTRIBUTE_GRAY_QUEUE;
-}
-
-static void
-gray_queue_redirect (SgenGrayQueue *queue)
+sgen_workers_get_job_gray_queue (WorkerData *worker_data, SgenGrayQueue *default_gray_queue)
 {
-       gboolean wake = FALSE;
-
-       for (;;) {
-               GrayQueueSection *section = sgen_gray_object_dequeue_section (queue);
-               if (!section)
-                       break;
-               sgen_section_gray_queue_enqueue ((SgenSectionGrayQueue *)queue->alloc_prepare_data, section);
-               wake = TRUE;
-       }
-
-       if (wake) {
-               g_assert (concurrent_collection_in_progress);
-               sgen_workers_ensure_awake ();
-       }
+       if (worker_data)
+               return &worker_data->private_gray_queue;
+       SGEN_ASSERT (0, default_gray_queue, "Why don't we have a default gray queue when we're not running in a worker thread?");
+       return default_gray_queue;
 }
 
 static void
 gray_queue_enable_redirect (SgenGrayQueue *queue)
 {
-       if (!concurrent_collection_in_progress)
-               return;
+       SGEN_ASSERT (0, concurrent_collection_in_progress, "Where are we redirecting the gray queue to, without a concurrent collection?");
 
-       sgen_gray_queue_set_alloc_prepare (queue, gray_queue_redirect, sgen_workers_get_distribute_section_gray_queue ());
-       gray_queue_redirect (queue);
+       sgen_gray_queue_set_alloc_prepare (queue, sgen_workers_take_from_queue_and_awake);
+       sgen_workers_take_from_queue_and_awake (queue);
 }
 
 void
@@ -537,7 +510,7 @@ gboolean
 sgen_drain_gray_stack (ScanCopyContext ctx)
 {
        ScanObjectFunc scan_func = ctx.ops->scan_object;
-       GrayQueue *queue = ctx.queue;
+       SgenGrayQueue *queue = ctx.queue;
 
        if (ctx.ops->drain_gray_stack)
                return ctx.ops->drain_gray_stack (queue);
@@ -734,7 +707,7 @@ pin_objects_in_nursery (gboolean do_scan_objects, ScanCopyContext ctx)
  * when we can't promote an object because we're out of memory.
  */
 void
-sgen_pin_object (GCObject *object, GrayQueue *queue)
+sgen_pin_object (GCObject *object, SgenGrayQueue *queue)
 {
        SGEN_ASSERT (0, sgen_ptr_in_nursery (object), "We're only supposed to use this for pinning nursery objects when out of memory.");
 
@@ -1329,20 +1302,25 @@ sgen_concurrent_collection_in_progress (void)
 typedef struct {
        SgenThreadPoolJob job;
        SgenObjectOperations *ops;
+       SgenGrayQueue *gc_thread_gray_queue;
 } ScanJob;
 
+static ScanCopyContext
+scan_copy_context_for_scan_job (void *worker_data_untyped, ScanJob *job)
+{
+       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
+
+       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)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
-       ScanJob *job_data = (ScanJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
-       remset.scan_remsets (ctx);
+       remset.scan_remsets (scan_copy_context_for_scan_job (worker_data_untyped, (ScanJob*)job));
 }
 
 typedef struct {
-       SgenThreadPoolJob job;
-       SgenObjectOperations *ops;
+       ScanJob scan_job;
        char *heap_start;
        char *heap_end;
        int root_type;
@@ -1351,16 +1329,14 @@ typedef struct {
 static void
 job_scan_from_registered_roots (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
        ScanFromRegisteredRootsJob *job_data = (ScanFromRegisteredRootsJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, &job_data->scan_job);
 
        scan_from_registered_roots (job_data->heap_start, job_data->heap_end, job_data->root_type, ctx);
 }
 
 typedef struct {
-       SgenThreadPoolJob job;
-       SgenObjectOperations *ops;
+       ScanJob scan_job;
        char *heap_start;
        char *heap_end;
 } ScanThreadDataJob;
@@ -1368,25 +1344,22 @@ typedef struct {
 static void
 job_scan_thread_data (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
        ScanThreadDataJob *job_data = (ScanThreadDataJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, &job_data->scan_job);
 
        sgen_client_scan_thread_data (job_data->heap_start, job_data->heap_end, TRUE, ctx);
 }
 
 typedef struct {
-       SgenThreadPoolJob job;
-       SgenObjectOperations *ops;
+       ScanJob scan_job;
        SgenPointerQueue *queue;
 } ScanFinalizerEntriesJob;
 
 static void
 job_scan_finalizer_entries (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
        ScanFinalizerEntriesJob *job_data = (ScanFinalizerEntriesJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, &job_data->scan_job);
 
        scan_finalizer_entries (job_data->queue, ctx);
 }
@@ -1394,9 +1367,8 @@ job_scan_finalizer_entries (void *worker_data_untyped, SgenThreadPoolJob *job)
 static void
 job_scan_major_mod_union_card_table (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
        ScanJob *job_data = (ScanJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
 
        g_assert (concurrent_collection_in_progress);
        major_collector.scan_card_table (CARDTABLE_SCAN_MOD_UNION, ctx);
@@ -1405,9 +1377,8 @@ job_scan_major_mod_union_card_table (void *worker_data_untyped, SgenThreadPoolJo
 static void
 job_scan_los_mod_union_card_table (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
        ScanJob *job_data = (ScanJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
 
        g_assert (concurrent_collection_in_progress);
        sgen_los_scan_card_table (CARDTABLE_SCAN_MOD_UNION, ctx);
@@ -1416,9 +1387,8 @@ job_scan_los_mod_union_card_table (void *worker_data_untyped, SgenThreadPoolJob
 static void
 job_mod_union_preclean (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       WorkerData *worker_data = (WorkerData *)worker_data_untyped;
        ScanJob *job_data = (ScanJob*)job;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
 
        g_assert (concurrent_collection_in_progress);
 
@@ -1429,15 +1399,15 @@ job_mod_union_preclean (void *worker_data_untyped, SgenThreadPoolJob *job)
 }
 
 static void
-init_gray_queue (gboolean use_workers)
+init_gray_queue (SgenGrayQueue *gc_thread_gray_queue, gboolean use_workers)
 {
        if (use_workers)
                sgen_workers_init_distribute_gray_queue ();
-       sgen_gray_object_queue_init (&gray_queue, NULL);
+       sgen_gray_object_queue_init (gc_thread_gray_queue, NULL, TRUE);
 }
 
 static void
-enqueue_scan_from_roots_jobs (char *heap_start, char *heap_end, SgenObjectOperations *ops, gboolean enqueue)
+enqueue_scan_from_roots_jobs (SgenGrayQueue *gc_thread_gray_queue, char *heap_start, char *heap_end, SgenObjectOperations *ops, gboolean enqueue)
 {
        ScanFromRegisteredRootsJob *scrrj;
        ScanThreadDataJob *stdj;
@@ -1446,38 +1416,43 @@ enqueue_scan_from_roots_jobs (char *heap_start, char *heap_end, SgenObjectOperat
        /* registered roots, this includes static fields */
 
        scrrj = (ScanFromRegisteredRootsJob*)sgen_thread_pool_job_alloc ("scan from registered roots normal", job_scan_from_registered_roots, sizeof (ScanFromRegisteredRootsJob));
-       scrrj->ops = ops;
+       scrrj->scan_job.ops = ops;
+       scrrj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
        scrrj->heap_start = heap_start;
        scrrj->heap_end = heap_end;
        scrrj->root_type = ROOT_TYPE_NORMAL;
-       sgen_workers_enqueue_job (&scrrj->job, enqueue);
+       sgen_workers_enqueue_job (&scrrj->scan_job.job, enqueue);
 
        scrrj = (ScanFromRegisteredRootsJob*)sgen_thread_pool_job_alloc ("scan from registered roots wbarrier", job_scan_from_registered_roots, sizeof (ScanFromRegisteredRootsJob));
-       scrrj->ops = ops;
+       scrrj->scan_job.ops = ops;
+       scrrj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
        scrrj->heap_start = heap_start;
        scrrj->heap_end = heap_end;
        scrrj->root_type = ROOT_TYPE_WBARRIER;
-       sgen_workers_enqueue_job (&scrrj->job, enqueue);
+       sgen_workers_enqueue_job (&scrrj->scan_job.job, enqueue);
 
        /* Threads */
 
        stdj = (ScanThreadDataJob*)sgen_thread_pool_job_alloc ("scan thread data", job_scan_thread_data, sizeof (ScanThreadDataJob));
-       stdj->ops = ops;
+       stdj->scan_job.ops = ops;
+       stdj->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
        stdj->heap_start = heap_start;
        stdj->heap_end = heap_end;
-       sgen_workers_enqueue_job (&stdj->job, enqueue);
+       sgen_workers_enqueue_job (&stdj->scan_job.job, enqueue);
 
        /* Scan the list of objects ready for finalization. */
 
        sfej = (ScanFinalizerEntriesJob*)sgen_thread_pool_job_alloc ("scan finalizer entries", job_scan_finalizer_entries, sizeof (ScanFinalizerEntriesJob));
+       sfej->scan_job.ops = ops;
+       sfej->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
        sfej->queue = &fin_ready_queue;
-       sfej->ops = ops;
-       sgen_workers_enqueue_job (&sfej->job, enqueue);
+       sgen_workers_enqueue_job (&sfej->scan_job.job, enqueue);
 
        sfej = (ScanFinalizerEntriesJob*)sgen_thread_pool_job_alloc ("scan critical finalizer entries", job_scan_finalizer_entries, sizeof (ScanFinalizerEntriesJob));
+       sfej->scan_job.ops = ops;
+       sfej->scan_job.gc_thread_gray_queue = gc_thread_gray_queue;
        sfej->queue = &critical_fin_queue;
-       sfej->ops = ops;
-       sgen_workers_enqueue_job (&sfej->job, enqueue);
+       sgen_workers_enqueue_job (&sfej->scan_job.job, enqueue);
 }
 
 /*
@@ -1493,10 +1468,13 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
        char *nursery_next;
        mword fragment_total;
        ScanJob *sj;
-       SgenObjectOperations *object_ops = &sgen_minor_collector.serial_ops;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, &gray_queue);
+       SgenGrayQueue gc_thread_gray_queue;
+       SgenObjectOperations *object_ops;
+       ScanCopyContext ctx;
        TV_DECLARE (atv);
        TV_DECLARE (btv);
+       SGEN_TV_DECLARE (last_minor_collection_start_tv);
+       SGEN_TV_DECLARE (last_minor_collection_end_tv);
 
        if (disable_minor_collections)
                return TRUE;
@@ -1506,6 +1484,11 @@ 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 (do_verify_nursery || do_dump_nursery_content)
                sgen_debug_verify_nursery (do_dump_nursery_content);
 
@@ -1541,7 +1524,8 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
 
        sgen_memgov_minor_collection_start ();
 
-       init_gray_queue (FALSE);
+       init_gray_queue (&gc_thread_gray_queue, FALSE);
+       ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, &gc_thread_gray_queue);
 
        gc_stats.minor_gc_count ++;
 
@@ -1549,8 +1533,6 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
                sgen_clear_nursery_fragments ();
                sgen_check_whole_heap (finish_up_concurrent_mark);
        }
-       if (consistency_check_at_minor_collection)
-               sgen_check_consistency ();
 
        sgen_process_fin_stage_entries ();
 
@@ -1567,6 +1549,9 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
        pin_objects_in_nursery (FALSE, ctx);
        sgen_pinning_trim_queue_to_section (nursery_section);
 
+       if (remset_consistency_checks)
+               sgen_check_remset_consistency ();
+
        TV_GETTIME (atv);
        time_minor_pinning += TV_ELAPSED (btv, atv);
        SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (btv, atv));
@@ -1574,6 +1559,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
 
        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);
 
        /* we don't have complete write barrier yet, so we scan all the old generation sections */
@@ -1589,7 +1575,7 @@ 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 (sgen_get_nursery_start (), nursery_next, object_ops, FALSE);
+       enqueue_scan_from_roots_jobs (&gc_thread_gray_queue, sgen_get_nursery_start (), nursery_next, object_ops, FALSE);
 
        TV_GETTIME (btv);
        time_minor_scan_roots += TV_ELAPSED (atv, btv);
@@ -1605,6 +1591,13 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
                sgen_pinning_setup_section (nursery_section);
        }
 
+       /*
+        * This is the latest point at which we can do this check, because
+        * sgen_build_nursery_fragments() unpins nursery objects again.
+        */
+       if (remset_consistency_checks)
+               sgen_check_remset_consistency ();
+
        /* walk the pin_queue, build up the fragment list of free memory, unmark
         * pinned objects as we go, memzero() the empty fragments so they are ready for the
         * next allocations.
@@ -1622,7 +1615,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
        time_minor_fragment_creation += TV_ELAPSED (atv, btv);
        SGEN_LOG (2, "Fragment creation: %lld usecs, %lu bytes available", (long long)TV_ELAPSED (atv, btv), (unsigned long)fragment_total);
 
-       if (consistency_check_at_minor_collection)
+       if (remset_consistency_checks)
                sgen_check_major_refs ();
 
        major_collector.finish_nursery_collection ();
@@ -1642,7 +1635,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_
        /* clear cemented hash */
        sgen_cement_clear_below_threshold ();
 
-       g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
+       sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
 
        remset.finish_minor_collection ();
 
@@ -1672,7 +1665,7 @@ typedef enum {
 } CopyOrMarkFromRootsMode;
 
 static void
-major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMode mode, SgenObjectOperations *object_ops)
+major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_next_pin_slot, CopyOrMarkFromRootsMode mode, SgenObjectOperations *object_ops)
 {
        LOSObject *bigobj;
        TV_DECLARE (atv);
@@ -1682,7 +1675,7 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
         */
        char *heap_start = NULL;
        char *heap_end = (char*)-1;
-       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, WORKERS_DISTRIBUTE_GRAY_QUEUE);
+       ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, gc_thread_gray_queue);
        gboolean concurrent = mode != COPY_OR_MARK_FROM_ROOTS_SERIAL;
 
        SGEN_ASSERT (0, !!concurrent == !!concurrent_collection_in_progress, "We've been called with the wrong mode.");
@@ -1698,8 +1691,6 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
                sgen_nursery_alloc_prepare_for_major ();
        }
 
-       init_gray_queue (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT);
-
        TV_GETTIME (atv);
 
        /* Pinning depends on this */
@@ -1777,7 +1768,7 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
                        }
                        sgen_los_pin_object (bigobj->data);
                        if (SGEN_OBJECT_HAS_REFERENCES (bigobj->data))
-                               GRAY_OBJECT_ENQUEUE (WORKERS_DISTRIBUTE_GRAY_QUEUE, bigobj->data, sgen_obj_get_descriptor ((GCObject*)bigobj->data));
+                               GRAY_OBJECT_ENQUEUE (gc_thread_gray_queue, bigobj->data, sgen_obj_get_descriptor ((GCObject*)bigobj->data));
                        sgen_pin_stats_register_object (bigobj->data, GENERATION_OLD);
                        SGEN_LOG (6, "Marked large object %p (%s) size: %lu from roots", bigobj->data,
                                        sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (bigobj->data)),
@@ -1791,10 +1782,17 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
        if (check_nursery_objects_pinned && !sgen_minor_collector.is_split)
                sgen_check_nursery_objects_pinned (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT);
 
-       major_collector.pin_objects (WORKERS_DISTRIBUTE_GRAY_QUEUE);
+       major_collector.pin_objects (gc_thread_gray_queue);
        if (old_next_pin_slot)
                *old_next_pin_slot = sgen_get_pinned_count ();
 
+       /*
+        * We don't actually pin when starting a concurrent collection, so the remset
+        * consistency check won't work.
+        */
+       if (remset_consistency_checks && mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT)
+               sgen_check_remset_consistency ();
+
        TV_GETTIME (btv);
        time_major_pinning += TV_ELAPSED (atv, btv);
        SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (atv, btv));
@@ -1825,7 +1823,7 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
 
        sgen_client_collecting_major_3 (&fin_ready_queue, &critical_fin_queue);
 
-       enqueue_scan_from_roots_jobs (heap_start, heap_end, object_ops, FALSE);
+       enqueue_scan_from_roots_jobs (gc_thread_gray_queue, heap_start, heap_end, object_ops, FALSE);
 
        TV_GETTIME (btv);
        time_major_scan_roots += TV_ELAPSED (atv, btv);
@@ -1841,11 +1839,12 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
                        /* Mod union preclean job */
                        sj = (ScanJob*)sgen_thread_pool_job_alloc ("preclean mod union cardtable", job_mod_union_preclean, sizeof (ScanJob));
                        sj->ops = object_ops;
+                       sj->gc_thread_gray_queue = NULL;
                        sgen_workers_start_all_workers (object_ops, &sj->job);
                } else {
                        sgen_workers_start_all_workers (object_ops, NULL);
                }
-               gray_queue_enable_redirect (WORKERS_DISTRIBUTE_GRAY_QUEUE);
+               gray_queue_enable_redirect (gc_thread_gray_queue);
        }
 
        if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
@@ -1854,10 +1853,12 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
                /* Mod union card table */
                sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan mod union cardtable", job_scan_major_mod_union_card_table, sizeof (ScanJob));
                sj->ops = object_ops;
+               sj->gc_thread_gray_queue = gc_thread_gray_queue;
                sgen_workers_enqueue_job (&sj->job, FALSE);
 
                sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan LOS mod union cardtable", job_scan_los_mod_union_card_table, sizeof (ScanJob));
                sj->ops = object_ops;
+               sj->gc_thread_gray_queue = gc_thread_gray_queue;
                sgen_workers_enqueue_job (&sj->job, FALSE);
 
                TV_GETTIME (atv);
@@ -1865,11 +1866,7 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
        }
 
        sgen_pin_stats_report ();
-}
 
-static void
-major_finish_copy_or_mark (CopyOrMarkFromRootsMode mode)
-{
        if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
                sgen_finish_pinning ();
 
@@ -1881,7 +1878,7 @@ major_finish_copy_or_mark (CopyOrMarkFromRootsMode mode)
 }
 
 static void
-major_start_collection (const char *reason, gboolean concurrent, size_t *old_next_pin_slot)
+major_start_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason, gboolean concurrent, size_t *old_next_pin_slot)
 {
        SgenObjectOperations *object_ops;
 
@@ -1889,7 +1886,7 @@ major_start_collection (const char *reason, gboolean concurrent, size_t *old_nex
 
        current_collection_generation = GENERATION_OLD;
 
-       g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
+       sgen_workers_assert_gray_queue_is_empty ();
 
        if (!concurrent)
                sgen_cement_reset ();
@@ -1919,12 +1916,11 @@ major_start_collection (const char *reason, gboolean concurrent, size_t *old_nex
        if (major_collector.start_major_collection)
                major_collector.start_major_collection ();
 
-       major_copy_or_mark_from_roots (old_next_pin_slot, concurrent ? COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT : COPY_OR_MARK_FROM_ROOTS_SERIAL, object_ops);
-       major_finish_copy_or_mark (concurrent ? COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT : COPY_OR_MARK_FROM_ROOTS_SERIAL);
+       major_copy_or_mark_from_roots (gc_thread_gray_queue, old_next_pin_slot, concurrent ? COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT : COPY_OR_MARK_FROM_ROOTS_SERIAL, object_ops);
 }
 
 static void
-major_finish_collection (const char *reason, gboolean is_overflow, size_t old_next_pin_slot, gboolean forced)
+major_finish_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason, gboolean is_overflow, size_t old_next_pin_slot, gboolean forced)
 {
        ScannedObjectCounts counts;
        SgenObjectOperations *object_ops;
@@ -1937,9 +1933,7 @@ major_finish_collection (const char *reason, gboolean is_overflow, size_t old_ne
        if (concurrent_collection_in_progress) {
                object_ops = &major_collector.major_ops_concurrent_finish;
 
-               major_copy_or_mark_from_roots (NULL, COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT, object_ops);
-
-               major_finish_copy_or_mark (COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT);
+               major_copy_or_mark_from_roots (gc_thread_gray_queue, NULL, COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT, object_ops);
 
 #ifdef SGEN_DEBUG_INTERNAL_ALLOC
                main_gc_thread = NULL;
@@ -1948,10 +1942,9 @@ major_finish_collection (const char *reason, gboolean is_overflow, size_t old_ne
                object_ops = &major_collector.major_ops_serial;
        }
 
-       g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
+       sgen_workers_assert_gray_queue_is_empty ();
 
-       /* all the objects in the heap */
-       finish_gray_stack (GENERATION_OLD, CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, &gray_queue));
+       finish_gray_stack (GENERATION_OLD, CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, gc_thread_gray_queue));
        TV_GETTIME (atv);
        time_major_finish_gray_stack += TV_ELAPSED (btv, atv);
 
@@ -1982,6 +1975,9 @@ major_finish_collection (const char *reason, gboolean is_overflow, size_t old_ne
        reset_heap_boundaries ();
        sgen_update_heap_boundaries ((mword)sgen_get_nursery_start (), (mword)sgen_get_nursery_end ());
 
+       if (whole_heap_check_before_collection)
+               sgen_check_whole_heap (FALSE);
+
        /* walk the pin_queue, build up the fragment list of free memory, unmark
         * pinned objects as we go, memzero() the empty fragments so they are ready for the
         * next allocations.
@@ -2035,15 +2031,13 @@ major_finish_collection (const char *reason, gboolean is_overflow, size_t old_ne
                sgen_client_finalize_notify ();
        }
 
-       g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
-
        sgen_memgov_major_collection_end (forced, concurrent_collection_in_progress, reason, is_overflow);
        current_collection_generation = -1;
 
        memset (&counts, 0, sizeof (ScannedObjectCounts));
        major_collector.finish_major_collection (&counts);
 
-       g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
+       sgen_workers_assert_gray_queue_is_empty ();
 
        SGEN_ASSERT (0, sgen_workers_all_done (), "Can't have workers working after major collection has finished");
        if (concurrent_collection_in_progress)
@@ -2064,6 +2058,7 @@ major_do_collection (const char *reason, gboolean is_overflow, gboolean forced)
        TV_DECLARE (time_start);
        TV_DECLARE (time_end);
        size_t old_next_pin_slot;
+       SgenGrayQueue gc_thread_gray_queue;
 
        if (disable_major_collections)
                return FALSE;
@@ -2076,8 +2071,10 @@ major_do_collection (const char *reason, gboolean is_overflow, gboolean forced)
        /* world must be stopped already */
        TV_GETTIME (time_start);
 
-       major_start_collection (reason, FALSE, &old_next_pin_slot);
-       major_finish_collection (reason, is_overflow, old_next_pin_slot, forced);
+       init_gray_queue (&gc_thread_gray_queue, FALSE);
+       major_start_collection (&gc_thread_gray_queue, reason, FALSE, &old_next_pin_slot);
+       major_finish_collection (&gc_thread_gray_queue, reason, is_overflow, old_next_pin_slot, forced);
+       sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
 
        TV_GETTIME (time_end);
        gc_stats.major_gc_time += TV_ELAPSED (time_start, time_end);
@@ -2095,6 +2092,7 @@ major_start_concurrent_collection (const char *reason)
        TV_DECLARE (time_start);
        TV_DECLARE (time_end);
        long long num_objects_marked;
+       SgenGrayQueue gc_thread_gray_queue;
 
        if (disable_major_collections)
                return;
@@ -2107,10 +2105,10 @@ major_start_concurrent_collection (const char *reason)
 
        binary_protocol_concurrent_start ();
 
+       init_gray_queue (&gc_thread_gray_queue, TRUE);
        // FIXME: store reason and pass it when finishing
-       major_start_collection (reason, TRUE, NULL);
-
-       gray_queue_redirect (&gray_queue);
+       major_start_collection (&gc_thread_gray_queue, reason, TRUE, NULL);
+       sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
 
        num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
 
@@ -2126,7 +2124,6 @@ major_start_concurrent_collection (const char *reason)
 static gboolean
 major_should_finish_concurrent_collection (void)
 {
-       SGEN_ASSERT (0, sgen_gray_object_queue_is_empty (&gray_queue), "Why is the gray queue not empty before we have started doing anything?");
        return sgen_workers_all_done ();
 }
 
@@ -2150,6 +2147,7 @@ major_update_concurrent_collection (void)
 static void
 major_finish_concurrent_collection (gboolean forced)
 {
+       SgenGrayQueue gc_thread_gray_queue;
        TV_DECLARE (total_start);
        TV_DECLARE (total_end);
 
@@ -2175,13 +2173,12 @@ major_finish_concurrent_collection (gboolean forced)
 
        current_collection_generation = GENERATION_OLD;
        sgen_cement_reset ();
-       major_finish_collection ("finishing", FALSE, -1, forced);
-
-       if (whole_heap_check_before_collection)
-               sgen_check_whole_heap (FALSE);
+       init_gray_queue (&gc_thread_gray_queue, FALSE);
+       major_finish_collection (&gc_thread_gray_queue, "finishing", FALSE, -1, forced);
+       sgen_gray_object_queue_dispose (&gc_thread_gray_queue);
 
        TV_GETTIME (total_end);
-       gc_stats.major_gc_time += TV_ELAPSED (total_start, total_end) - TV_ELAPSED (last_minor_collection_start_tv, last_minor_collection_end_tv);
+       gc_stats.major_gc_time += TV_ELAPSED (total_start, total_end);
 
        current_collection_generation = -1;
 }
@@ -2305,8 +2302,6 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const
                degraded_mode = 1;
        }
 
-       g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
-
        TV_GETTIME (gc_total_end);
        time_max = MAX (time_max, TV_ELAPSED (gc_total_start, gc_total_end));
 
@@ -2408,6 +2403,13 @@ sgen_object_is_live (GCObject *obj)
  */
 
 static volatile gboolean pending_unqueued_finalizer = FALSE;
+volatile gboolean sgen_suspend_finalizers = FALSE;
+
+void
+sgen_set_suspend_finalizers (void)
+{
+       sgen_suspend_finalizers = TRUE;
+}
 
 int
 sgen_gc_invoke_finalizers (void)
@@ -2463,6 +2465,8 @@ sgen_gc_invoke_finalizers (void)
 gboolean
 sgen_have_pending_finalizers (void)
 {
+       if (sgen_suspend_finalizers)
+               return FALSE;
        return pending_unqueued_finalizer || !sgen_pointer_queue_is_empty (&fin_ready_queue) || !sgen_pointer_queue_is_empty (&critical_fin_queue);
 }
 
@@ -3031,8 +3035,8 @@ sgen_gc_init (void)
                                collect_before_allocs = atoi (arg);
                        } else if (!strcmp (opt, "verify-before-collections")) {
                                whole_heap_check_before_collection = TRUE;
-                       } else if (!strcmp (opt, "check-at-minor-collections")) {
-                               consistency_check_at_minor_collection = TRUE;
+                       } else if (!strcmp (opt, "check-remset-consistency")) {
+                               remset_consistency_checks = TRUE;
                                nursery_clear_policy = CLEAR_AT_GC;
                        } else if (!strcmp (opt, "mod-union-consistency-check")) {
                                if (!major_collector.is_concurrent) {
@@ -3098,7 +3102,7 @@ sgen_gc_init (void)
                                fprintf (stderr, "Valid <option>s are:\n");
                                fprintf (stderr, "  collect-before-allocs[=<n>]\n");
                                fprintf (stderr, "  verify-before-allocs[=<n>]\n");
-                               fprintf (stderr, "  check-at-minor-collections\n");
+                               fprintf (stderr, "  check-remset-consistency\n");
                                fprintf (stderr, "  check-mark-bits\n");
                                fprintf (stderr, "  check-nursery-pinned\n");
                                fprintf (stderr, "  verify-before-collections\n");
index c08502dc55e2e0517bbf59df732619f56ae42748..a517035499306398ce354ef0bff9957ecf6a181d 100644 (file)
@@ -557,6 +557,7 @@ typedef struct {
        GCObject* (*alloc_for_promotion) (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references);
 
        SgenObjectOperations serial_ops;
+       SgenObjectOperations serial_ops_with_concurrent_major;
 
        void (*prepare_to_space) (char *to_space_bitmap, size_t space_bitmap_size);
        void (*clear_fragments) (void);
@@ -813,8 +814,9 @@ void sgen_process_fin_stage_entries (void);
 gboolean sgen_have_pending_finalizers (void);
 void sgen_object_register_for_finalization (GCObject *obj, void *user_data);
 
-void sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data, volatile gboolean *suspend);
+void sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data);
 void sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation);
+void sgen_set_suspend_finalizers (void);
 
 void sgen_register_disappearing_link (GCObject *obj, void **link, gboolean track, gboolean in_gc);
 
@@ -977,7 +979,7 @@ extern NurseryClearPolicy nursery_clear_policy;
 extern gboolean sgen_try_free_some_memory;
 extern mword total_promoted_size;
 extern mword total_allocated_major;
-
+extern volatile gboolean sgen_suspend_finalizers;
 extern MonoCoopMutex gc_mutex;
 
 /* Nursery helpers. */
@@ -1011,7 +1013,7 @@ GCObject* sgen_alloc_obj_mature (GCVTable vtable, size_t size);
 
 /* Debug support */
 
-void sgen_check_consistency (void);
+void sgen_check_remset_consistency (void);
 void sgen_check_mod_union_consistency (void);
 void sgen_check_major_refs (void);
 void sgen_check_whole_heap (gboolean allow_missing_pinning);
index 809215136f9799d817b0b157d6c1ac972f085f93..9b5f92a19547916049f9129c7ed8a1fd360497c8 100644 (file)
@@ -38,6 +38,12 @@ guint64 stat_gray_queue_dequeue_slow_path;
 #define STATE_ASSERT(s,v)
 #endif
 
+/*
+ * Whenever we dispose a gray queue, we save its free list.  Then, in the next collection,
+ * we reuse that free list for the new gray queue.
+ */
+static GrayQueueSection *last_gray_queue_free_list;
+
 void
 sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue)
 {
@@ -212,48 +218,40 @@ sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue)
 }
 
 void
-sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func)
+sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func, gboolean reuse_free_list)
 {
-       g_assert (sgen_gray_object_queue_is_empty (queue));
+       memset (queue, 0, sizeof (SgenGrayQueue));
 
-       queue->alloc_prepare_func = NULL;
-       queue->alloc_prepare_data = NULL;
 #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
        queue->enqueue_check_func = enqueue_check_func;
 #endif
 
-       /* Free the extra sections allocated during the last collection */
-       sgen_gray_object_queue_trim_free_list (queue);
-}
-
-static void
-invalid_prepare_func (SgenGrayQueue *queue)
-{
-       g_assert_not_reached ();
+       if (reuse_free_list) {
+               queue->free_list = last_gray_queue_free_list;
+               last_gray_queue_free_list = NULL;
+       }
 }
 
 void
-sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue)
+sgen_gray_object_queue_dispose (SgenGrayQueue *queue)
 {
-       sgen_gray_object_queue_init (queue, NULL);
-       queue->alloc_prepare_func = invalid_prepare_func;
-       queue->alloc_prepare_data = NULL;
-}
+       SGEN_ASSERT (0, sgen_gray_object_queue_is_empty (queue), "Why are we disposing a gray queue that's not empty?");
 
-void
-sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func, void *data)
-{
-       SGEN_ASSERT (0, !queue->alloc_prepare_func && !queue->alloc_prepare_data, "Can't set gray queue alloc-prepare twice");
-       queue->alloc_prepare_func = alloc_prepare_func;
-       queue->alloc_prepare_data = data;
+       /* Free the extra sections allocated during the last collection */
+       sgen_gray_object_queue_trim_free_list (queue);
+
+       SGEN_ASSERT (0, !last_gray_queue_free_list, "Are we disposing two gray queues after another?");
+       last_gray_queue_free_list = queue->free_list;
+
+       /* just to make sure */
+       memset (queue, 0, sizeof (SgenGrayQueue));
 }
 
 void
-sgen_gray_object_queue_init_with_alloc_prepare (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func,
-               GrayQueueAllocPrepareFunc alloc_prepare_func, void *data)
+sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func)
 {
-       sgen_gray_object_queue_init (queue, enqueue_check_func);
-       sgen_gray_queue_set_alloc_prepare (queue, alloc_prepare_func, data);
+       SGEN_ASSERT (0, !queue->alloc_prepare_func, "Can't set gray queue alloc-prepare twice");
+       queue->alloc_prepare_func = alloc_prepare_func;
 }
 
 void
@@ -268,13 +266,6 @@ sgen_gray_object_queue_deinit (SgenGrayQueue *queue)
        }
 }
 
-void
-sgen_gray_object_queue_disable_alloc_prepare (SgenGrayQueue *queue)
-{
-       queue->alloc_prepare_func = NULL;
-       queue->alloc_prepare_data = NULL;
-}
-
 static void
 lock_section_queue (SgenSectionGrayQueue *queue)
 {
index 019f44c927c8e5fbee00e0d291c0234cb54b73cb..2a872d7d2bf1816193f06f8dfebec7a035cfb4d1 100644 (file)
@@ -97,7 +97,6 @@ struct _SgenGrayQueue {
 #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
        GrayQueueEnqueueCheckFunc enqueue_check_func;
 #endif
-       void *alloc_prepare_data;
 };
 
 typedef struct _SgenSectionGrayQueue SgenSectionGrayQueue;
@@ -130,13 +129,10 @@ GrayQueueEntry sgen_gray_object_dequeue (SgenGrayQueue *queue);
 GrayQueueSection* sgen_gray_object_dequeue_section (SgenGrayQueue *queue);
 void sgen_gray_object_enqueue_section (SgenGrayQueue *queue, GrayQueueSection *section);
 void sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue);
-void sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func);
-void sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue);
-void sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func, void *data);
-void sgen_gray_object_queue_init_with_alloc_prepare (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func,
-               GrayQueueAllocPrepareFunc func, void *data);
+void sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func, gboolean reuse_free_list);
+void sgen_gray_object_queue_dispose (SgenGrayQueue *queue);
+void sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func);
 void sgen_gray_object_queue_deinit (SgenGrayQueue *queue);
-void sgen_gray_object_queue_disable_alloc_prepare (SgenGrayQueue *queue);
 void sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue);
 void sgen_gray_object_free_queue_section (GrayQueueSection *section);
 
index 4b52eefb3f00cdf295504d29a21780667e99f144..c032d1946f41c18b3dcf1df001b2f1b976025253 100644 (file)
@@ -526,12 +526,14 @@ sgen_ptr_is_in_los (char *ptr, char **start)
 {
        LOSObject *obj;
 
-       *start = NULL;
+       if (start)
+               *start = NULL;
        for (obj = los_object_list; obj; obj = obj->next) {
                char *end = (char*)obj->data + sgen_los_object_size (obj);
 
                if (ptr >= (char*)obj->data && ptr < end) {
-                       *start = (char*)obj->data;
+                       if (start)
+                               *start = (char*)obj->data;
                        return TRUE;
                }
        }
index 6a20d0c57fad1e275e2ffc9e213c3bd385f94155..aa5ef1a44a93ace9fe040a3089e3bcffbf19f93e 100644 (file)
@@ -563,17 +563,41 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references)
 }
 
 static gboolean
-ptr_is_from_pinned_alloc (char *ptr)
+ptr_is_in_major_block (char *ptr, char **start, gboolean *pinned)
 {
        MSBlockInfo *block;
 
        FOREACH_BLOCK_NO_LOCK (block) {
-               if (ptr >= MS_BLOCK_FOR_BLOCK_INFO (block) && ptr <= MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE)
-                       return block->pinned;
+               if (ptr >= MS_BLOCK_FOR_BLOCK_INFO (block) && ptr <= MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE) {
+                       int count = MS_BLOCK_FREE / block->obj_size;
+                       int i;
+
+                       if (start)
+                               *start = NULL;
+                       for (i = 0; i <= count; ++i) {
+                               if (ptr >= (char*)MS_BLOCK_OBJ (block, i) && ptr < (char*)MS_BLOCK_OBJ (block, i + 1)) {
+                                       if (start)
+                                               *start = (char *)MS_BLOCK_OBJ (block, i);
+                                       break;
+                               }
+                       }
+                       if (pinned)
+                               *pinned = block->pinned;
+                       return TRUE;
+               }
        } END_FOREACH_BLOCK_NO_LOCK;
        return FALSE;
 }
 
+static gboolean
+ptr_is_from_pinned_alloc (char *ptr)
+{
+       gboolean pinned;
+       if (ptr_is_in_major_block (ptr, NULL, &pinned))
+               return pinned;
+       return FALSE;
+}
+
 static void
 ensure_can_access_block_free_list (MSBlockInfo *block)
 {
@@ -772,23 +796,9 @@ major_is_object_live (GCObject *obj)
 static gboolean
 major_ptr_is_in_non_pinned_space (char *ptr, char **start)
 {
-       MSBlockInfo *block;
-
-       FOREACH_BLOCK_NO_LOCK (block) {
-               if (ptr >= MS_BLOCK_FOR_BLOCK_INFO (block) && ptr <= MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE) {
-                       int count = MS_BLOCK_FREE / block->obj_size;
-                       int i;
-
-                       *start = NULL;
-                       for (i = 0; i <= count; ++i) {
-                               if (ptr >= (char*)MS_BLOCK_OBJ (block, i) && ptr < (char*)MS_BLOCK_OBJ (block, i + 1)) {
-                                       *start = (char *)MS_BLOCK_OBJ (block, i);
-                                       break;
-                               }
-                       }
-                       return !block->pinned;
-               }
-       } END_FOREACH_BLOCK_NO_LOCK;
+       gboolean pinned;
+       if (ptr_is_in_major_block (ptr, start, &pinned))
+               return !pinned;
        return FALSE;
 }
 
index a77d53b4744bed22af7beefdba02232bbb373c22..da392c4292847badfe7fcc5a9b01e9c2cb082851 100644 (file)
@@ -8,12 +8,35 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#define collector_pin_object(obj, queue) sgen_pin_object (obj, queue);
-#define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion
+#undef SERIAL_COPY_OBJECT
+#undef SERIAL_COPY_OBJECT_FROM_OBJ
 
-extern guint64 stat_nursery_copy_object_failed_to_space; /* from sgen-gc.c */
+#if defined(SGEN_SIMPLE_NURSERY)
+
+#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
+#else
+#define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object
+#define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj
+#endif
+
+#elif defined (SGEN_SPLIT_NURSERY)
+
+#ifdef SGEN_CONCURRENT_MAJOR
+#define SERIAL_COPY_OBJECT split_nursery_serial_with_concurrent_major_copy_object
+#define SERIAL_COPY_OBJECT_FROM_OBJ split_nursery_serial_with_concurrent_major_copy_object_from_obj
+#else
+#define SERIAL_COPY_OBJECT split_nursery_serial_copy_object
+#define SERIAL_COPY_OBJECT_FROM_OBJ split_nursery_serial_copy_object_from_obj
+#endif
+
+#else
+#error "No nursery configuration specified"
+#endif
 
-#include "sgen-copy-object.h"
+
+extern guint64 stat_nursery_copy_object_failed_to_space; /* from sgen-gc.c */
 
 /*
  * This is how the copying happens from the nursery to the old generation.
@@ -121,6 +144,10 @@ SERIAL_COPY_OBJECT_FROM_OBJ (GCObject **obj_slot, SgenGrayQueue *queue)
                SGEN_ASSERT (9, sgen_obj_get_descriptor (forwarded),  "forwarded object %p has no gc descriptor", forwarded);
                SGEN_LOG (9, " (already forwarded to %p)", forwarded);
                HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded);
+#ifdef SGEN_CONCURRENT_MAJOR
+               /* See comment on STORE_STORE_FENCE below. */
+               STORE_STORE_FENCE;
+#endif
                SGEN_UPDATE_REFERENCE (obj_slot, forwarded);
 #ifndef SGEN_SIMPLE_NURSERY
                if (G_UNLIKELY (sgen_ptr_in_nursery (forwarded) && !sgen_ptr_in_nursery (obj_slot) && !SGEN_OBJECT_IS_CEMENTED (forwarded)))
@@ -187,6 +214,16 @@ SERIAL_COPY_OBJECT_FROM_OBJ (GCObject **obj_slot, SgenGrayQueue *queue)
        HEAVY_STAT (++stat_objects_copied_nursery);
 
        copy = copy_object_no_checks (obj, queue);
+#ifdef SGEN_CONCURRENT_MAJOR
+       /*
+        * If an object is evacuated to the major heap and a reference to it, from the major
+        * heap, updated, the concurrent major collector might follow that reference and
+        * scan the new major object.  To make sure the object contents are seen by the
+        * major collector we need this write barrier, so that the reference is seen after
+        * the object.
+        */
+       STORE_STORE_FENCE;
+#endif
        SGEN_UPDATE_REFERENCE (obj_slot, copy);
 #ifndef SGEN_SIMPLE_NURSERY
        if (G_UNLIKELY (sgen_ptr_in_nursery (copy) && !sgen_ptr_in_nursery (obj_slot) && !SGEN_OBJECT_IS_CEMENTED (copy)))
@@ -199,7 +236,3 @@ SERIAL_COPY_OBJECT_FROM_OBJ (GCObject **obj_slot, SgenGrayQueue *queue)
        }
 #endif
 }
-
-#define FILL_MINOR_COLLECTOR_COPY_OBJECT(collector)    do {                    \
-               (collector)->serial_ops.copy_or_mark_object = SERIAL_COPY_OBJECT;                       \
-       } while (0)
index 4b62a739f27183622a0dbc4441e1ea2b17536b9c..cc3e7a4539e794037d54c6055196b2d9df815fef 100644 (file)
 
 extern guint64 stat_scan_object_called_nursery;
 
+#undef SERIAL_SCAN_OBJECT
+#undef SERIAL_SCAN_VTYPE
+#undef SERIAL_SCAN_PTR_FIELD
+
 #if defined(SGEN_SIMPLE_NURSERY)
+
+#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
+#define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_with_concurrent_major_scan_ptr_field
+#else
 #define SERIAL_SCAN_OBJECT simple_nursery_serial_scan_object
 #define SERIAL_SCAN_VTYPE simple_nursery_serial_scan_vtype
+#define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_scan_ptr_field
+#endif
 
 #elif defined (SGEN_SPLIT_NURSERY)
+
+#ifdef SGEN_CONCURRENT_MAJOR
+#define SERIAL_SCAN_OBJECT split_nursery_serial_with_concurrent_major_scan_object
+#define SERIAL_SCAN_VTYPE split_nursery_serial_with_concurrent_major_scan_vtype
+#define SERIAL_SCAN_PTR_FIELD split_nursery_serial_with_concurrent_major_scan_ptr_field
+#else
 #define SERIAL_SCAN_OBJECT split_nursery_serial_scan_object
 #define SERIAL_SCAN_VTYPE split_nursery_serial_scan_vtype
+#define SERIAL_SCAN_PTR_FIELD split_nursery_serial_scan_ptr_field
+#endif
 
 #else
-#error "Please define GC_CONF_NAME"
+#error "No nursery configuration specified"
 #endif
 
 #undef HANDLE_PTR
@@ -75,8 +95,8 @@ SERIAL_SCAN_PTR_FIELD (GCObject *full_object, GCObject **ptr, SgenGrayQueue *que
        HANDLE_PTR (ptr, NULL);
 }
 
-#define FILL_MINOR_COLLECTOR_SCAN_OBJECT(collector)    do {                    \
-               (collector)->serial_ops.scan_object = SERIAL_SCAN_OBJECT;       \
-               (collector)->serial_ops.scan_vtype = SERIAL_SCAN_VTYPE; \
-               (collector)->serial_ops.scan_ptr_field = SERIAL_SCAN_PTR_FIELD; \
+#define FILL_MINOR_COLLECTOR_SCAN_OBJECT(ops)  do {                    \
+               (ops)->scan_object = SERIAL_SCAN_OBJECT;                        \
+               (ops)->scan_vtype = SERIAL_SCAN_VTYPE;                  \
+               (ops)->scan_ptr_field = SERIAL_SCAN_PTR_FIELD;          \
        } while (0)
index 2e59b6359a4b1aea6f4e650998ae1590e4318d50..ce504201f62d7ce42f8c0f5d64df086f7ed9d786 100644 (file)
@@ -262,27 +262,33 @@ binary_protocol_check_file_overflow (void)
  *
  * The protocol entries that do flush have `FLUSH()` in their definition.
  */
-void
+gboolean
 binary_protocol_flush_buffers (gboolean force)
 {
 #ifdef HAVE_UNISTD_H
        int num_buffers = 0, i;
+       BinaryProtocolBuffer *header;
        BinaryProtocolBuffer *buf;
        BinaryProtocolBuffer **bufs;
 
        if (binary_protocol_file == -1)
-               return;
+               return FALSE;
 
        if (!force && !try_lock_exclusive ())
-               return;
+               return FALSE;
 
-       for (buf = binary_protocol_buffers; buf != NULL; buf = buf->next)
+       header = binary_protocol_buffers;
+       for (buf = header; buf != NULL; buf = buf->next)
                ++num_buffers;
        bufs = (BinaryProtocolBuffer **)sgen_alloc_internal_dynamic (num_buffers * sizeof (BinaryProtocolBuffer*), INTERNAL_MEM_BINARY_PROTOCOL, TRUE);
-       for (buf = binary_protocol_buffers, i = 0; buf != NULL; buf = buf->next, i++)
+       for (buf = header, i = 0; buf != NULL; buf = buf->next, i++)
                bufs [i] = buf;
        SGEN_ASSERT (0, i == num_buffers, "Binary protocol buffer count error");
 
+       /*
+        * This might be incorrect when forcing, but all bets are off in that case, anyway,
+        * because we're trying to figure out a bug in the debugger.
+        */
        binary_protocol_buffers = NULL;
 
        for (i = num_buffers - 1; i >= 0; --i) {
@@ -294,6 +300,8 @@ binary_protocol_flush_buffers (gboolean force)
 
        if (!force)
                unlock_exclusive ();
+
+       return TRUE;
 #endif
 }
 
index 1c10d29d5c0e367f07e8d26a0163177da59c1b41..adefb98070bd5538b5d4a50442c311ef68dac853 100644 (file)
@@ -154,7 +154,7 @@ enum {
 void binary_protocol_init (const char *filename, long long limit);
 gboolean binary_protocol_is_enabled (void);
 
-void binary_protocol_flush_buffers (gboolean force);
+gboolean binary_protocol_flush_buffers (gboolean force);
 
 #define BEGIN_PROTOCOL_ENTRY0(method) \
        void method (void);
index 62c14a5392bc394ffef8420e9741629b458d1b2b..bc8aee7044c8a12baaa684e9411893dedf9f567a 100644 (file)
@@ -18,6 +18,7 @@
 #include "mono/sgen/sgen-protocol.h"
 #include "mono/sgen/sgen-layout-stats.h"
 #include "mono/sgen/sgen-client.h"
+#include "mono/utils/mono-memory-model.h"
 
 static inline GCObject*
 alloc_for_promotion (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references)
@@ -61,14 +62,35 @@ init_nursery (SgenFragmentAllocator *allocator, char *start, char *end)
 
 /******************************************Copy/Scan functins ************************************************/
 
+#define collector_pin_object(obj, queue) sgen_pin_object (obj, queue);
+#define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion
+
+#include "sgen-copy-object.h"
+
 #define SGEN_SIMPLE_NURSERY
 
-#define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object
-#define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj
+#include "sgen-minor-copy-object.h"
+#include "sgen-minor-scan-object.h"
+
+static void
+fill_serial_ops (SgenObjectOperations *ops)
+{
+       ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
+       FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
+}
+
+#define SGEN_CONCURRENT_MAJOR
 
 #include "sgen-minor-copy-object.h"
 #include "sgen-minor-scan-object.h"
 
+static void
+fill_serial_with_concurrent_major_ops (SgenObjectOperations *ops)
+{
+       ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
+       FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
+}
+
 void
 sgen_simple_nursery_init (SgenMinorCollector *collector)
 {
@@ -83,8 +105,8 @@ sgen_simple_nursery_init (SgenMinorCollector *collector)
        collector->build_fragments_finish = build_fragments_finish;
        collector->init_nursery = init_nursery;
 
-       FILL_MINOR_COLLECTOR_COPY_OBJECT (collector);
-       FILL_MINOR_COLLECTOR_SCAN_OBJECT (collector);
+       fill_serial_ops (&collector->serial_ops);
+       fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major);
 }
 
 
index 3b7ae668a203d537bd2372d15d62e7630c5db7e6..a4deb5a3c6a702d2e65b37c1530102f8767776dc 100644 (file)
@@ -418,14 +418,35 @@ print_gc_param_usage (void)
 
 /******************************************Copy/Scan functins ************************************************/
 
+#define collector_pin_object(obj, queue) sgen_pin_object (obj, queue);
+#define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion
+
+#include "sgen-copy-object.h"
+
 #define SGEN_SPLIT_NURSERY
 
-#define SERIAL_COPY_OBJECT split_nursery_serial_copy_object
-#define SERIAL_COPY_OBJECT_FROM_OBJ split_nursery_serial_copy_object_from_obj
+#include "sgen-minor-copy-object.h"
+#include "sgen-minor-scan-object.h"
+
+static void
+fill_serial_ops (SgenObjectOperations *ops)
+{
+       ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
+       FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
+}
+
+#define SGEN_CONCURRENT_MAJOR
 
 #include "sgen-minor-copy-object.h"
 #include "sgen-minor-scan-object.h"
 
+static void
+fill_serial_with_concurrent_major_ops (SgenObjectOperations *ops)
+{
+       ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
+       FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
+}
+
 void
 sgen_split_nursery_init (SgenMinorCollector *collector)
 {
@@ -442,8 +463,8 @@ sgen_split_nursery_init (SgenMinorCollector *collector)
        collector->handle_gc_param = handle_gc_param;
        collector->print_gc_param_usage = print_gc_param_usage;
 
-       FILL_MINOR_COLLECTOR_COPY_OBJECT (collector);
-       FILL_MINOR_COLLECTOR_SCAN_OBJECT (collector);
+       fill_serial_ops (&collector->serial_ops);
+       fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major);
 }
 
 
index adc600a090f3dc801f8d1b16b4796acb28a69988..dfdff8c9062f2a7e25f8b5d5591ebc1b1b598187 100644 (file)
@@ -77,7 +77,7 @@ state_is_working_or_enqueued (State state)
        return state == STATE_WORKING || state == STATE_WORK_ENQUEUED;
 }
 
-void
+static void
 sgen_workers_ensure_awake (void)
 {
        State old_state;
@@ -177,7 +177,8 @@ static void
 init_private_gray_queue (WorkerData *data)
 {
        sgen_gray_object_queue_init (&data->private_gray_queue,
-                       sgen_get_major_collector ()->is_concurrent ? concurrent_enqueue_check : NULL);
+                       sgen_get_major_collector ()->is_concurrent ? concurrent_enqueue_check : NULL,
+                       FALSE);
 }
 
 static void
@@ -354,10 +355,29 @@ sgen_workers_are_working (void)
        return state_is_working_or_enqueued (workers_state);
 }
 
-SgenSectionGrayQueue*
-sgen_workers_get_distribute_section_gray_queue (void)
+void
+sgen_workers_assert_gray_queue_is_empty (void)
 {
-       return &workers_distribute_gray_queue;
+       SGEN_ASSERT (0, sgen_section_gray_queue_is_empty (&workers_distribute_gray_queue), "Why is the workers gray queue not empty?");
+}
+
+void
+sgen_workers_take_from_queue_and_awake (SgenGrayQueue *queue)
+{
+       gboolean wake = FALSE;
+
+       for (;;) {
+               GrayQueueSection *section = sgen_gray_object_dequeue_section (queue);
+               if (!section)
+                       break;
+               sgen_section_gray_queue_enqueue (&workers_distribute_gray_queue, section);
+               wake = TRUE;
+       }
+
+       if (wake) {
+               SGEN_ASSERT (0, sgen_concurrent_collection_in_progress (), "Why is there work to take when there's no concurrent collection in progress?");
+               sgen_workers_ensure_awake ();
+       }
 }
 
 #endif
index 780d2eb6df921ed6a096879c4876eef75f8adbaf..1a66c79a48c238fd5ae4e3b589bc4e6e8f5ca4bf 100644 (file)
@@ -20,7 +20,6 @@ struct _WorkerData {
 void sgen_workers_init (int num_workers);
 void sgen_workers_stop_all_workers (void);
 void sgen_workers_start_all_workers (SgenObjectOperations *object_ops, SgenThreadPoolJob *finish_job);
-void sgen_workers_ensure_awake (void);
 void sgen_workers_init_distribute_gray_queue (void);
 void sgen_workers_enqueue_job (SgenThreadPoolJob *job, gboolean enqueue);
 void sgen_workers_wait_for_jobs_finished (void);
@@ -30,6 +29,7 @@ void sgen_workers_join (void);
 gboolean sgen_workers_have_idle_work (void);
 gboolean sgen_workers_all_done (void);
 gboolean sgen_workers_are_working (void);
-SgenSectionGrayQueue* sgen_workers_get_distribute_section_gray_queue (void);
+void sgen_workers_assert_gray_queue_is_empty (void);
+void sgen_workers_take_from_queue_and_awake (SgenGrayQueue *queue);
 
 #endif
index 92ae719d7ba653080ecada657c71f3263678dba8..1bd0a646054f2e7e7586ad1e8b46b4ce2c215969 100644 (file)
@@ -23,16 +23,16 @@ struct _MonoCoopCond {
        mono_cond_t c;
 };
 
-static inline gint
+static inline void
 mono_coop_mutex_init (MonoCoopMutex *mutex)
 {
-       return mono_os_mutex_init (&mutex->m);
+       mono_os_mutex_init (&mutex->m);
 }
 
-static inline gint
+static inline void
 mono_coop_mutex_init_recursive (MonoCoopMutex *mutex)
 {
-       return mono_os_mutex_init_recursive (&mutex->m);
+       mono_os_mutex_init_recursive (&mutex->m);
 }
 
 static inline gint
@@ -41,22 +41,18 @@ mono_coop_mutex_destroy (MonoCoopMutex *mutex)
        return mono_os_mutex_destroy (&mutex->m);
 }
 
-static inline gint
+static inline void
 mono_coop_mutex_lock (MonoCoopMutex *mutex)
 {
-       gint res;
-
        /* Avoid thread state switch if lock is not contended */
        if (mono_os_mutex_trylock (&mutex->m) == 0)
-               return 0;
+               return;
 
        MONO_ENTER_GC_SAFE;
 
-       res = mono_os_mutex_lock (&mutex->m);
+       mono_os_mutex_lock (&mutex->m);
 
        MONO_EXIT_GC_SAFE;
-
-       return res;
 }
 
 static inline gint
@@ -65,16 +61,16 @@ mono_coop_mutex_trylock (MonoCoopMutex *mutex)
        return mono_os_mutex_trylock (&mutex->m);
 }
 
-static inline gint
+static inline void
 mono_coop_mutex_unlock (MonoCoopMutex *mutex)
 {
-       return mono_os_mutex_unlock (&mutex->m);
+       mono_os_mutex_unlock (&mutex->m);
 }
 
-static inline gint
+static inline void
 mono_coop_cond_init (MonoCoopCond *cond)
 {
-       return mono_os_cond_init (&cond->c);
+       mono_os_cond_init (&cond->c);
 }
 
 static inline gint
@@ -83,18 +79,14 @@ mono_coop_cond_destroy (MonoCoopCond *cond)
        return mono_os_cond_destroy (&cond->c);
 }
 
-static inline gint
+static inline void
 mono_coop_cond_wait (MonoCoopCond *cond, MonoCoopMutex *mutex)
 {
-       gint res;
-
        MONO_ENTER_GC_SAFE;
 
-       res = mono_os_cond_wait (&cond->c, &mutex->m);
+       mono_os_cond_wait (&cond->c, &mutex->m);
 
        MONO_EXIT_GC_SAFE;
-
-       return res;
 }
 
 static inline gint
@@ -111,16 +103,16 @@ mono_coop_cond_timedwait (MonoCoopCond *cond, MonoCoopMutex *mutex, guint32 time
        return res;
 }
 
-static inline gint
+static inline void
 mono_coop_cond_signal (MonoCoopCond *cond)
 {
-       return mono_os_cond_signal (&cond->c);
+       mono_os_cond_signal (&cond->c);
 }
 
-static inline gint
+static inline void
 mono_coop_cond_broadcast (MonoCoopCond *cond)
 {
-       return mono_os_cond_broadcast (&cond->c);
+       mono_os_cond_broadcast (&cond->c);
 }
 
 G_END_DECLS
index 81c987ed74070107a4400e07f8fabf28b6cf865a..29937c5b73877e18c63ae2b49365bb6bf328de6f 100644 (file)
@@ -18,16 +18,16 @@ struct _MonoCoopSem {
        MonoSemType s;
 };
 
-static inline gint
+static inline void
 mono_coop_sem_init (MonoCoopSem *sem, int value)
 {
-       return mono_os_sem_init (&sem->s, value);
+       mono_os_sem_init (&sem->s, value);
 }
 
-static inline gint
+static inline void
 mono_coop_sem_destroy (MonoCoopSem *sem)
 {
-       return mono_os_sem_destroy (&sem->s);
+       mono_os_sem_destroy (&sem->s);
 }
 
 static inline gint
@@ -44,10 +44,10 @@ mono_coop_sem_wait (MonoCoopSem *sem, MonoSemFlags flags)
        return res;
 }
 
-static inline gint
+static inline MonoSemTimedwaitRet
 mono_coop_sem_timedwait (MonoCoopSem *sem, guint timeout_ms, MonoSemFlags flags)
 {
-       gint res;
+       MonoSemTimedwaitRet res;
 
        MONO_ENTER_GC_SAFE;
 
@@ -58,10 +58,10 @@ mono_coop_sem_timedwait (MonoCoopSem *sem, guint timeout_ms, MonoSemFlags flags)
        return res;
 }
 
-static inline gint
+static inline void
 mono_coop_sem_post (MonoCoopSem *sem)
 {
-       return mono_os_sem_post (&sem->s);
+       mono_os_sem_post (&sem->s);
 }
 
 G_END_DECLS
index d5621323f9f64289ae8e3396cb5f7aaf99f48d23..758c3dc6fc2651487fc8cc87fcd97714f1882d13 100644 (file)
@@ -159,7 +159,8 @@ mono_hwcap_arch_init (void)
 
        if (file) {
                while ((line = fgets (buf, 512, file))) {
-                       if (!strncmp (line, "Processor", 9)) {
+                       if (!strncmp (line, "Processor", 9) ||
+                           !strncmp (line, "model name", 10)) {
                                char *ver = strstr (line, "(v");
 
                                if (ver) {
index b82b968a0262f1fe8b9791aa4c204cf6ceb80fc6..ece9bd410f6142aa38b59773fbdd144ed1d60c07 100644 (file)
@@ -43,76 +43,113 @@ G_BEGIN_DECLS
 typedef pthread_mutex_t mono_mutex_t;
 typedef pthread_cond_t mono_cond_t;
 
-static inline int
+static inline void
 mono_os_mutex_init (mono_mutex_t *mutex)
 {
-       return pthread_mutex_init (mutex, NULL);
+       int res;
+
+       res = pthread_mutex_init (mutex, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
-static inline int
+static inline void
 mono_os_mutex_init_recursive (mono_mutex_t *mutex)
 {
        int res;
        pthread_mutexattr_t attr;
 
-       pthread_mutexattr_init (&attr);
-       pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+       res = pthread_mutexattr_init (&attr);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
        res = pthread_mutex_init (mutex, &attr);
-       pthread_mutexattr_destroy (&attr);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 
-       return res;
+       res = pthread_mutexattr_destroy (&attr);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
 static inline int
 mono_os_mutex_destroy (mono_mutex_t *mutex)
 {
-       return pthread_mutex_destroy (mutex);
+       int res;
+
+       res = pthread_mutex_destroy (mutex);
+       if (G_UNLIKELY (res != 0 && res != EBUSY))
+               g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_mutex_lock (mono_mutex_t *mutex)
 {
        int res;
 
        res = pthread_mutex_lock (mutex);
-       g_assert (res != EINVAL);
-
-       return res;
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
 static inline int
 mono_os_mutex_trylock (mono_mutex_t *mutex)
 {
-       return pthread_mutex_trylock (mutex);
+       int res;
+
+       res = pthread_mutex_trylock (mutex);
+       if (G_UNLIKELY (res != 0 && res != EBUSY))
+               g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_mutex_unlock (mono_mutex_t *mutex)
 {
-       return pthread_mutex_unlock (mutex);
+       int res;
+
+       res = pthread_mutex_unlock (mutex);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
-static inline int
+static inline void
 mono_os_cond_init (mono_cond_t *cond)
 {
-       return pthread_cond_init (cond, NULL);
+       int res;
+
+       res = pthread_cond_init (cond, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
 static inline int
 mono_os_cond_destroy (mono_cond_t *cond)
 {
-       return pthread_cond_destroy (cond);
+       int res;
+
+       res = pthread_cond_destroy (cond);
+       if (G_UNLIKELY (res != 0 && res != EBUSY))
+               g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
 {
        int res;
 
        res = pthread_cond_wait (cond, mutex);
-       g_assert (res != EINVAL);
-
-       return res;
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
 static inline int
@@ -123,12 +160,17 @@ mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_
        gint64 usecs;
        int res;
 
-       if (timeout_ms == MONO_INFINITE_WAIT)
-               return mono_os_cond_wait (cond, mutex);
+       if (timeout_ms == MONO_INFINITE_WAIT) {
+               mono_os_cond_wait (cond, mutex);
+               return 0;
+       }
 
        /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
 
-       gettimeofday (&tv, NULL);
+       res = gettimeofday (&tv, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
        tv.tv_sec += timeout_ms / 1000;
        usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
        if (usecs >= 1000000) {
@@ -139,21 +181,30 @@ mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_
        ts.tv_nsec = usecs * 1000;
 
        res = pthread_cond_timedwait (cond, mutex, &ts);
-       g_assert (res != EINVAL);
+       if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
+               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 
-       return res;
+       return res != 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_cond_signal (mono_cond_t *cond)
 {
-       return pthread_cond_signal (cond);
+       int res;
+
+       res = pthread_cond_signal (cond);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
-static inline int
+static inline void
 mono_os_cond_broadcast (mono_cond_t *cond)
 {
-       return pthread_cond_broadcast (cond);
+       int res;
+
+       res = pthread_cond_broadcast (cond);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
 #else
@@ -225,18 +276,24 @@ WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCritical
 typedef CRITICAL_SECTION mono_mutex_t;
 typedef CONDITION_VARIABLE mono_cond_t;
 
-static inline int
+static inline void
 mono_os_mutex_init (mono_mutex_t *mutex)
 {
-       InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
-       return 0;
+       BOOL res;
+
+       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
 }
 
-static inline int
+static inline void
 mono_os_mutex_init_recursive (mono_mutex_t *mutex)
 {
-       InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
-       return 0;
+       BOOL res;
+
+       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
 }
 
 static inline int
@@ -246,31 +303,28 @@ mono_os_mutex_destroy (mono_mutex_t *mutex)
        return 0;
 }
 
-static inline int
+static inline void
 mono_os_mutex_lock (mono_mutex_t *mutex)
 {
        EnterCriticalSection (mutex);
-       return 0;
 }
 
 static inline int
 mono_os_mutex_trylock (mono_mutex_t *mutex)
 {
-       return TryEnterCriticalSection (mutex) != 0 ? 0 : 1;
+       return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_mutex_unlock (mono_mutex_t *mutex)
 {
        LeaveCriticalSection (mutex);
-       return 0;
 }
 
-static inline int
+static inline void
 mono_os_cond_init (mono_cond_t *cond)
 {
        InitializeConditionVariable (cond);
-       return 0;
 }
 
 static inline int
@@ -280,30 +334,38 @@ mono_os_cond_destroy (mono_cond_t *cond)
        return 0;
 }
 
-static inline int
+static inline void
 mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
 {
-       return SleepConditionVariableCS (cond, mutex, INFINITE) ? 0 : 1;
+       BOOL res;
+
+       res = SleepConditionVariableCS (cond, mutex, INFINITE);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
 }
 
 static inline int
 mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
 {
-       return SleepConditionVariableCS (cond, mutex, timeout_ms) ? 0 : 1;
+       BOOL res;
+
+       res = SleepConditionVariableCS (cond, mutex, timeout_ms);
+       if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
+               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+
+       return res == 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_cond_signal (mono_cond_t *cond)
 {
        WakeConditionVariable (cond);
-       return 0;
 }
 
-static inline int
+static inline void
 mono_os_cond_broadcast (mono_cond_t *cond)
 {
        WakeAllConditionVariable (cond);
-       return 0;
 }
 
 #endif
index 6282457e13e87fe673753909f197c1d6118eb102..9f59ce1ea821df2fa3dd849edd89d8e3a8b8aee7 100644 (file)
@@ -51,30 +51,45 @@ typedef enum {
        MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
 } MonoSemFlags;
 
+typedef enum {
+       MONO_SEM_TIMEDWAIT_RET_SUCCESS  =  0,
+       MONO_SEM_TIMEDWAIT_RET_ALERTED  = -1,
+       MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
+} MonoSemTimedwaitRet;
+
 #if defined(USE_MACH_SEMA)
 
 typedef semaphore_t MonoSemType;
 
-static inline int
+static inline void
 mono_os_sem_init (MonoSemType *sem, int value)
 {
-       return semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value) != KERN_SUCCESS ? -1 : 0;
+       kern_return_t res;
+
+       res = semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value);
+       if (G_UNLIKELY (res != KERN_SUCCESS))
+               g_error ("%s: semaphore_create failed with error %d", __func__, res);
 }
 
-static inline int
+static inline void
 mono_os_sem_destroy (MonoSemType *sem)
 {
-       return semaphore_destroy (current_task (), *sem) != KERN_SUCCESS ? -1 : 0;
+       kern_return_t res;
+
+       res = semaphore_destroy (current_task (), *sem);
+       if (G_UNLIKELY (res != KERN_SUCCESS))
+               g_error ("%s: semaphore_destroy failed with error %d", __func__, res);
 }
 
 static inline int
 mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
 {
-       int res;
+       kern_return_t res;
 
 retry:
        res = semaphore_wait (*sem);
-       g_assert (res != KERN_INVALID_ARGUMENT);
+       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+               g_error ("%s: semaphore_wait failed with error %d", __func__, res);
 
        if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE))
                goto retry;
@@ -82,15 +97,16 @@ retry:
        return res != KERN_SUCCESS ? -1 : 0;
 }
 
-static inline int
+static inline MonoSemTimedwaitRet
 mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
 {
+       kern_return_t res;
+       int resint;
        mach_timespec_t ts, copy;
        struct timeval start, current;
-       int res = 0;
 
        if (timeout_ms == MONO_INFINITE_WAIT)
-               return mono_os_sem_wait (sem, flags);
+               return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
 
        ts.tv_sec = timeout_ms / 1000;
        ts.tv_nsec = (timeout_ms % 1000) * 1000000;
@@ -100,16 +116,22 @@ mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
        }
 
        copy = ts;
-       gettimeofday (&start, NULL);
+       resint = gettimeofday (&start, NULL);
+       if (G_UNLIKELY (resint != 0))
+               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 
 retry:
        res = semaphore_timedwait (*sem, ts);
-       g_assert (res != KERN_INVALID_ARGUMENT);
+       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED && res != KERN_OPERATION_TIMED_OUT))
+               g_error ("%s: semaphore_timedwait failed with error %d", __func__, res);
 
        if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
                ts = copy;
 
-               gettimeofday (&current, NULL);
+               resint = gettimeofday (&current, NULL);
+               if (G_UNLIKELY (resint != 0))
+                       g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
                ts.tv_sec -= (current.tv_sec - start.tv_sec);
                ts.tv_nsec -= (current.tv_usec - start.tv_usec) * 1000;
                if (ts.tv_nsec < 0) {
@@ -128,37 +150,54 @@ retry:
                goto retry;
        }
 
-       return res != KERN_SUCCESS ? -1 : 0;
+       switch (res) {
+       case KERN_SUCCESS:
+               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+       case KERN_ABORTED:
+               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+       case KERN_OPERATION_TIMED_OUT:
+               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+       default:
+               g_assert_not_reached ();
+       }
 }
 
-static inline int
+static inline void
 mono_os_sem_post (MonoSemType *sem)
 {
-       int res;
+       kern_return_t res;
+
 retry:
        res = semaphore_signal (*sem);
-       g_assert (res != KERN_INVALID_ARGUMENT);
+       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+               g_error ("%s: semaphore_signal failed with error %d", __func__, res);
 
        if (res == KERN_ABORTED)
                goto retry;
-
-       return res != KERN_SUCCESS ? -1 : 0;
 }
 
 #elif !defined(HOST_WIN32) && defined(HAVE_SEMAPHORE_H)
 
 typedef sem_t MonoSemType;
 
-static inline int
+static inline void
 mono_os_sem_init (MonoSemType *sem, int value)
 {
-       return sem_init (sem, 0, value);
+       int res;
+
+       res = sem_init (sem, 0, value);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: sem_init failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 }
 
-static inline int
+static inline void
 mono_os_sem_destroy (MonoSemType *sem)
 {
-       return sem_destroy (sem);
+       int res;
+
+       res = sem_destroy (sem);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: sem_destroy failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 }
 
 static inline int
@@ -168,34 +207,44 @@ mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
 
 retry:
        res = sem_wait (sem);
-       if (res == -1)
-               g_assert (errno != EINVAL);
+       if (G_UNLIKELY (res != 0 && errno != EINTR))
+               g_error ("%s: sem_wait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 
-       if (res == -1 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+       if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
                goto retry;
 
        return res != 0 ? -1 : 0;
 }
 
-static inline int
+static inline MonoSemTimedwaitRet
 mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
 {
        struct timespec ts, copy;
        struct timeval t;
-       int res = 0;
+       int res;
 
        if (timeout_ms == 0) {
-               res = sem_trywait (sem) != 0 ? -1 : 0;
-               if (res == -1)
-                       g_assert (errno != EINVAL);
-
-               return res != 0 ? -1 : 0;
+               res = sem_trywait (sem);
+               if (G_UNLIKELY (res != 0 && errno != EINTR && errno != EAGAIN))
+                       g_error ("%s: sem_trywait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+               if (res == 0)
+                       return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+               else if (errno == EINTR)
+                       return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+               else if (errno == EAGAIN)
+                       return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+               else
+                       g_assert_not_reached ();
        }
 
        if (timeout_ms == MONO_INFINITE_WAIT)
-               return mono_os_sem_wait (sem, flags);
+               return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
+
+       res = gettimeofday (&t, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 
-       gettimeofday (&t, NULL);
        ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
        ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
        while (ts.tv_nsec >= NSEC_PER_SEC) {
@@ -206,75 +255,96 @@ mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
        copy = ts;
 
 retry:
-#if defined(__native_client__) && defined(USE_NEWLIB)
-       res = sem_trywait (sem);
-#else
        res = sem_timedwait (sem, &ts);
-#endif
-       if (res == -1)
-               g_assert (errno != EINVAL);
+       if (G_UNLIKELY (res != 0 && errno != EINTR && errno != ETIMEDOUT))
+               g_error ("%s: sem_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 
-       if (res == -1 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
+       if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
                ts = copy;
                goto retry;
        }
 
-       return res != 0 ? -1 : 0;
+       if (res == 0)
+               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+       else if (errno == EINTR)
+               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+       else if (errno == ETIMEDOUT)
+               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+       else
+               g_assert_not_reached ();
 }
 
-static inline int
+static inline void
 mono_os_sem_post (MonoSemType *sem)
 {
        int res;
 
        res = sem_post (sem);
-       if (res == -1)
-               g_assert (errno != EINVAL);
-
-       return res;
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: sem_post failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
 }
 
 #else
 
 typedef HANDLE MonoSemType;
 
-static inline int
+static inline void
 mono_os_sem_init (MonoSemType *sem, int value)
 {
        *sem = CreateSemaphore (NULL, value, 0x7FFFFFFF, NULL);
-       return *sem == NULL ? -1 : 0;
+       if (G_UNLIKELY (*sem == NULL))
+               g_error ("%s: CreateSemaphore failed with error %d", __func__, GetLastError ());
 }
 
-static inline int
+static inline void
 mono_os_sem_destroy (MonoSemType *sem)
 {
-       return !CloseHandle (*sem) ? -1 : 0;
+       BOOL res;
+
+       res = CloseHandle (*sem);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
 }
 
-static inline int
+static inline MonoSemTimedwaitRet
 mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
 {
-       gboolean res;
+       BOOL res;
 
 retry:
        res = WaitForSingleObjectEx (*sem, timeout_ms, flags & MONO_SEM_FLAGS_ALERTABLE);
+       if (G_UNLIKELY (res != WAIT_OBJECT_0 && res != WAIT_IO_COMPLETION && res != WAIT_TIMEOUT))
+               g_error ("%s: WaitForSingleObjectEx failed with error %d", __func__, GetLastError ());
 
        if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
                goto retry;
 
-       return res != WAIT_OBJECT_0 ? -1 : 0;
+       switch (res) {
+       case WAIT_OBJECT_0:
+               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+       case WAIT_IO_COMPLETION:
+               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+       case WAIT_TIMEOUT:
+               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+       default:
+               g_assert_not_reached ();
+       }
 }
 
 static inline int
 mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
 {
-       return mono_os_sem_timedwait (sem, INFINITE, flags);
+       return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
 }
 
-static inline int
+static inline void
 mono_os_sem_post (MonoSemType *sem)
 {
-       return !ReleaseSemaphore (*sem, 1, NULL) ? -1 : 0;
+       BOOL res;
+
+       res = ReleaseSemaphore (*sem, 1, NULL);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: ReleaseSemaphore failed with error %d", __func__, GetLastError ());
 }
 
 #endif
index adf14f22eaf802f541bcabef1e24cba8fb8f1d99..cb218f5c14d3d3e88957435fb7c5b6d1c5aea175 100644 (file)
@@ -61,8 +61,7 @@ inner_start_thread (void *arg)
        /* Register the thread with the io-layer */
        handle = wapi_create_thread_handle ();
        if (!handle) {
-               res = mono_coop_sem_post (&(start_info->registered));
-               g_assert (!res);
+               mono_coop_sem_post (&(start_info->registered));
                return NULL;
        }
        start_info->handle = handle;
@@ -80,8 +79,7 @@ inner_start_thread (void *arg)
        }
 
        /* start_info is not valid after this */
-       res = mono_coop_sem_post (&(start_info->registered));
-       g_assert (!res);
+       mono_coop_sem_post (&(start_info->registered));
        start_info = NULL;
 
        if (flags & CREATE_SUSPENDED) {
index 1b9dd43daf1f9350fc5aac916c862b8ae42c7451..c824cf314d03419a83d1041fef4a3e24a91b5ab8 100644 (file)
@@ -156,8 +156,7 @@ inner_start_thread (LPVOID arg)
        info->runtime_thread = TRUE;
        info->create_suspended = suspend;
 
-       post_result = mono_coop_sem_post (&(start_info->registered));
-       g_assert (!post_result);
+       mono_coop_sem_post (&(start_info->registered));
 
        if (suspend) {
                WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
index 07d7b26ce0185b966074e577a5810dd4d4143fd2..d9791d0764b48f78100f799c7a802c422df7a29e 100644 (file)
@@ -238,7 +238,7 @@ mono_threads_wait_pending_operations (void)
                for (i = 0; i < pending_suspends; ++i) {
                        THREADS_SUSPEND_DEBUG ("[INITIATOR-WAIT-WAITING]\n");
                        InterlockedIncrement (&waits_done);
-                       if (!mono_os_sem_timedwait (&suspend_semaphore, sleepAbortDuration, MONO_SEM_FLAGS_NONE))
+                       if (mono_os_sem_timedwait (&suspend_semaphore, sleepAbortDuration, MONO_SEM_FLAGS_NONE) == MONO_SEM_TIMEDWAIT_RET_SUCCESS)
                                continue;
                        mono_stopwatch_stop (&suspension_time);
 
index d8a34dc426964cf0c15526f7597c4c1058cf392c..eb0c22ed323f9372692a686347f75d42514880b2 100644 (file)
@@ -142,7 +142,6 @@ void
 mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast)
 {
        MonoW32HandleBase *handle_data;
-       int thr_ret;
 
        if (!mono_w32handle_lookup_data (handle, &handle_data)) {
                return;
@@ -159,10 +158,7 @@ mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broad
                /* The condition the global signal cond is waiting on is the signalling of
                 * _any_ handle. So lock it before setting the signalled state.
                 */
-               thr_ret = mono_os_mutex_lock (&global_signal_mutex);
-               if (thr_ret != 0)
-                       g_warning ("Bad call to mono_os_mutex_lock result %d for global signal mutex", thr_ret);
-               g_assert (thr_ret == 0);
+               mono_os_mutex_lock (&global_signal_mutex);
 
                /* This function _must_ be called with
                 * handle->signal_mutex locked
@@ -170,29 +166,17 @@ mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broad
                handle_data->signalled=state;
 
                if (broadcast == TRUE) {
-                       thr_ret = mono_os_cond_broadcast (&handle_data->signal_cond);
-                       if (thr_ret != 0)
-                               g_warning ("Bad call to mono_os_cond_broadcast result %d for handle %p", thr_ret, handle);
-                       g_assert (thr_ret == 0);
+                       mono_os_cond_broadcast (&handle_data->signal_cond);
                } else {
-                       thr_ret = mono_os_cond_signal (&handle_data->signal_cond);
-                       if (thr_ret != 0)
-                               g_warning ("Bad call to mono_os_cond_signal result %d for handle %p", thr_ret, handle);
-                       g_assert (thr_ret == 0);
+                       mono_os_cond_signal (&handle_data->signal_cond);
                }
 
                /* Tell everyone blocking on multiple handles that something
                 * was signalled
                 */
-               thr_ret = mono_os_cond_broadcast (&global_signal_cond);
-               if (thr_ret != 0)
-                       g_warning ("Bad call to mono_os_cond_broadcast result %d for handle %p", thr_ret, handle);
-               g_assert (thr_ret == 0);
+               mono_os_cond_broadcast (&global_signal_cond);
 
-               thr_ret = mono_os_mutex_unlock (&global_signal_mutex);
-               if (thr_ret != 0)
-                       g_warning ("Bad call to mono_os_mutex_unlock result %d for global signal mutex", thr_ret);
-               g_assert (thr_ret == 0);
+               mono_os_mutex_unlock (&global_signal_mutex);
        } else {
                handle_data->signalled=state;
        }
@@ -217,7 +201,9 @@ mono_w32handle_lock_signal_mutex (void)
        g_message ("%s: lock global signal mutex", __func__);
 #endif
 
-       return(mono_os_mutex_lock (&global_signal_mutex));
+       mono_os_mutex_lock (&global_signal_mutex);
+
+       return 0;
 }
 
 int
@@ -227,7 +213,9 @@ mono_w32handle_unlock_signal_mutex (void)
        g_message ("%s: unlock global signal mutex", __func__);
 #endif
 
-       return(mono_os_mutex_unlock (&global_signal_mutex));
+       mono_os_mutex_unlock (&global_signal_mutex);
+
+       return 0;
 }
 
 int
@@ -245,7 +233,9 @@ mono_w32handle_lock_handle (gpointer handle)
 
        mono_w32handle_ref (handle);
 
-       return(mono_os_mutex_lock (&handle_data->signal_mutex));
+       mono_os_mutex_lock (&handle_data->signal_mutex);
+
+       return 0;
 }
 
 int
@@ -276,7 +266,6 @@ int
 mono_w32handle_unlock_handle (gpointer handle)
 {
        MonoW32HandleBase *handle_data;
-       int ret;
 
 #ifdef DEBUG
        g_message ("%s: unlocking handle %p", __func__, handle);
@@ -286,11 +275,11 @@ mono_w32handle_unlock_handle (gpointer handle)
                return(0);
        }
 
-       ret = mono_os_mutex_unlock (&handle_data->signal_mutex);
+       mono_os_mutex_unlock (&handle_data->signal_mutex);
 
        mono_w32handle_unref (handle);
 
-       return(ret);
+       return 0;
 }
 
 /*
@@ -358,19 +347,14 @@ mono_w32handle_cleanup (void)
 static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
                               MonoW32HandleType type, gpointer handle_specific)
 {
-       int thr_ret;
-       
        g_assert (!shutting_down);
        
        handle->type = type;
        handle->signalled = FALSE;
        handle->ref = 1;
 
-       thr_ret = mono_os_cond_init (&handle->signal_cond);
-       g_assert (thr_ret == 0);
-
-       thr_ret = mono_os_mutex_init (&handle->signal_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_cond_init (&handle->signal_cond);
+       mono_os_mutex_init (&handle->signal_mutex);
 
        if (handle_specific)
                handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
@@ -439,7 +423,6 @@ mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
 {
        guint32 handle_idx = 0;
        gpointer handle;
-       int thr_ret;
 
        g_assert (!shutting_down);
 
@@ -448,8 +431,7 @@ mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
 
        g_assert(!type_is_fd(type));
 
-       thr_ret = mono_os_mutex_lock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_lock (&scan_mutex);
 
        while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == 0) {
                /* Try and expand the array, and have another go */
@@ -464,8 +446,7 @@ mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
                private_handles_slots_count ++;
        }
 
-       thr_ret = mono_os_mutex_unlock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&scan_mutex);
 
        if (handle_idx == 0) {
                /* We ran out of slots */
@@ -489,7 +470,6 @@ gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
 {
        MonoW32HandleBase *handle_data;
        int fd_index, fd_offset;
-       int thr_ret;
 
        g_assert (!shutting_down);
 
@@ -509,14 +489,12 @@ gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
 
        /* Initialize the array entries on demand */
        if (!private_handles [fd_index]) {
-               thr_ret = mono_os_mutex_lock (&scan_mutex);
-               g_assert (thr_ret == 0);
+               mono_os_mutex_lock (&scan_mutex);
 
                if (!private_handles [fd_index])
                        private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
 
-               thr_ret = mono_os_mutex_unlock (&scan_mutex);
-               g_assert (thr_ret == 0);
+               mono_os_mutex_unlock (&scan_mutex);
        }
 
        handle_data = &private_handles [fd_index][fd_offset];
@@ -562,10 +540,8 @@ mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpoi
        MonoW32HandleBase *handle_data = NULL;
        gpointer handle;
        guint32 i, k;
-       int thr_ret;
 
-       thr_ret = mono_os_mutex_lock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_lock (&scan_mutex);
 
        for (i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
                if (private_handles [i]) {
@@ -581,8 +557,7 @@ mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpoi
        }
 
 done:
-       thr_ret = mono_os_mutex_unlock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&scan_mutex);
 }
 
 /* This might list some shared handles twice if they are already
@@ -603,10 +578,8 @@ gpointer mono_w32handle_search (MonoW32HandleType type,
        gpointer ret = NULL;
        guint32 i, k;
        gboolean found = FALSE;
-       int thr_ret;
 
-       thr_ret = mono_os_mutex_lock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_lock (&scan_mutex);
 
        for (i = SLOT_INDEX (0); !found && i < private_handles_slots_count; i++) {
                if (private_handles [i]) {
@@ -625,8 +598,7 @@ gpointer mono_w32handle_search (MonoW32HandleType type,
                }
        }
 
-       thr_ret = mono_os_mutex_unlock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&scan_mutex);
 
        if (!found) {
                ret = NULL;
@@ -699,8 +671,7 @@ static void mono_w32handle_unref_full (gpointer handle, gboolean ignore_private_
                type = handle_data->type;
                handle_specific = handle_data->specific;
 
-               thr_ret = mono_os_mutex_lock (&scan_mutex);
-               g_assert (thr_ret == 0);
+               mono_os_mutex_lock (&scan_mutex);
 
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Destroying handle %p", __func__, handle);
 
@@ -726,8 +697,7 @@ static void mono_w32handle_unref_full (gpointer handle, gboolean ignore_private_
 
                memset (handle_data, 0, sizeof (MonoW32HandleBase));
 
-               thr_ret = mono_os_mutex_unlock (&scan_mutex);
-               g_assert (thr_ret == 0);
+               mono_os_mutex_unlock (&scan_mutex);
 
                if (early_exit)
                        return;
@@ -1166,10 +1136,8 @@ void mono_w32handle_dump (void)
 {
        MonoW32HandleBase *handle_data;
        guint32 i, k;
-       int thr_ret;
 
-       thr_ret = mono_os_mutex_lock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_lock (&scan_mutex);
 
        for(i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
                if (private_handles [i]) {
@@ -1191,8 +1159,7 @@ void mono_w32handle_dump (void)
                }
        }
 
-       thr_ret = mono_os_mutex_unlock (&scan_mutex);
-       g_assert (thr_ret == 0);
+       mono_os_mutex_unlock (&scan_mutex);
 }
 
 #endif /* !defined(HOST_WIN32) */
index ad2fe82914140b24f6daa4d5025b2f5b7bd995c5..17656e390a572516baf18e227d260af94c972691 100755 (executable)
@@ -20,6 +20,9 @@ if [[ ${label} == 'w64' ]]; then PLATFORM=x64; EXTRA_CONF_FLAGS="${EXTRA_CONF_FL
 if [[ ${CI_TAGS} == 'mobile_static' ]];
     then
     EXTRA_CONF_FLAGS="${EXTRA_CONF_FLAGS} --with-runtime_preset=mobile_static";
+elif [[ ${CI_TAGS} == 'acceptance-tests' ]];
+    then
+    EXTRA_CONF_FLAGS="${EXTRA_CONF_FLAGS} --prefix=${WORKSPACE}/tmp/mono-acceptance-tests --with-sgen-default-concurrent=yes";
 elif [[ ${label} != w* ]] && [[ ${label} != 'debian-ppc64el' ]] && [[ ${label} != 'centos-s390x' ]];
     then
     # Override the defaults to skip profiles
@@ -52,4 +55,7 @@ if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]];
     # we don't run the test suite on Windows PRs, we just ensure the build succeeds, so end here
 fi
 
-make check-ci
+if [[ ${CI_TAGS} == 'acceptance-tests' ]];
+then $(dirname "${BASH_SOURCE[0]}")/run-test-acceptance-tests.sh
+else make check-ci
+fi
\ No newline at end of file
diff --git a/scripts/ci/run-test-acceptance-tests.sh b/scripts/ci/run-test-acceptance-tests.sh
new file mode 100755 (executable)
index 0000000..0e5fe78
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash -e
+
+export TESTCMD=`dirname "${BASH_SOURCE[0]}"`/run-step.sh
+
+make install  # Roslyn tests need a Mono installation
+
+LANG=en_US.UTF-8 ${TESTCMD} --label=check-ms-test-suite --timeout=30m make -C acceptance-tests check-ms-test-suite
+
+total_tests=$(find acceptance-tests/ -name TestResult*xml | xargs cat | grep -c "<test-case")
+if [ "$total_tests" -lt "1600" ]
+       then echo "*** NOT ENOUGH TEST RESULTS RECORDED, MARKING FAILURE ***"
+       exit 1
+fi
+
+${TESTCMD} --label=check-roslyn --timeout=30m make -C acceptance-tests check-roslyn PREFIX=${WORKSPACE}/tmp/mono-acceptance-tests
+rm -rf ${WORKSPACE}/tmp/mono-acceptance-tests  # cleanup the Mono installation used for Roslyn tests
+
+${TESTCMD} --label=coreclr-compile-tests --timeout=80m --fatal make -C acceptance-tests coreclr-compile-tests
+${TESTCMD} --label=coreclr-runtest-basic --timeout=10m make -C acceptance-tests coreclr-runtest-basic
+${TESTCMD} --label=coreclr-runtest-coremanglib --timeout=10m make -C acceptance-tests coreclr-runtest-coremanglib
+${TESTCMD} --label=coreclr-gcstress --timeout=1200m make -C acceptance-tests coreclr-gcstress
index 3ecee62fd998986ccb4369062f2c69822055a9e7..bffda6b73f7191f1673b4e3123ca9c18b95589ea 100755 (executable)
@@ -38,6 +38,7 @@ ${TESTCMD} --label=Microsoft.Build.Framework --timeout=5m make -w -C mcs/class/M
 ${TESTCMD} --label=Microsoft.Build.Tasks --timeout=5m make -w -C mcs/class/Microsoft.Build.Tasks run-test
 ${TESTCMD} --label=Microsoft.Build.Utilities --timeout=5m make -w -C mcs/class/Microsoft.Build.Utilities run-test
 ${TESTCMD} --label=Mono.C5 --timeout=5m make -w -C mcs/class/Mono.C5 run-test
+${TESTCMD} --label=Mono.Tasklets --timeout=5m make -w -C mcs/class/Mono.Tasklets run-test
 ${TESTCMD} --label=System.Configuration --timeout=5m make -w -C mcs/class/System.Configuration run-test
 ${TESTCMD} --label=System.Transactions --timeout=5m make -w -C mcs/class/System.Transactions run-test
 ${TESTCMD} --label=System.Web.Extensions --timeout=5m make -w -C mcs/class/System.Web.Extensions run-test