Mono 4.0.0 Release Notes

Highlights

Adoption of Microsoft’s open source code

C# 6.0

Floating point optimizations

We dropped support for the 2.0, 3.5 and 4.0 assemblies

Updated IKVM

Lighter Debugger overhead

Basic PowerPC64 LE support

Floating Point Optimizations

Mono has historically chosen to use the highest possible precision for all floating point operations. This means that both 64-bit math and 32-bit math were done with the highest precision available.

But performance sensitive code that might not need high precision was negatively impacted.

With this release we are introducing support for performing 32-bit floating operations using 32-bit math. This produces faster code at the expense of fidelity. This mode of operation can be enabled with the -O=float32 option.

With a sample Mandelbrot generator program, on x86-64 these are the results:

ARM32 x86-64 Original 1m56 17.2 Original/LLVM 10.3 Float32 1m12 12.2 Float32/LLVM 8.8

This option currently needs to be enabled manually, it is not part of the -O=all options.

C#

Mono’s C# compiler now defaults to C# 6.0

The compiler will now avoid generating a GUID each time it builds, generating identical builds across recompilations. Following the steps of Roslyn’s new default.

Microsoft Source Code Adoption

This is the first release of Mono that replaces various components of Mono with code that was released by Microsoft under the MIT license in one of three places:

Microsoft’s ReferenceSource drop

Microsoft’s CoreFX

Microsoft’s CoreCLR

While Microsoft is working towards .NET Core: a redistributable and re-imagined version of .NET, the project remains a work in progress. Mono at this point continues to provide an API that tracks the .NET desktop/server version.

This means that most of the code that we have integrated comes from the ReferenceSource drop. In the future, we will deliver a “Mono Core” along the same lines of .NET Core to allow the use of the Mono runtime with the new library distribution system that is being developed with CoreFX.

In this release, we have ported components that were either incomplete or buggy in Mono and were relatively easy to port to Mono. There is much more to be done in this area. If you are interested in tracking those efforts, check the project status:

https://trello.com/b/vRPTMfdz/net-framework-integration-into-mono

Mono ships now with a subset of the referencesource that have been adjusted to work with Mono’s class libraries or have been updated to be cross platform.

Decimal

We have replaced Mono’s System.Decimal implementation with Microsoft’s version. This fixed a couple of formatting bugs. While Mono’s code did not have any major bugs, Microsoft’s implementation is more efficient and is actively maintained. Fixing bugs in System.Decimal was always difficult.

Assorted Microsoft Classes Imported

These are some highlights of code imported from Microsoft (smaller bits like attributes, enumerations, event arguments, exceptions or other simple bits are not shown):

The following namespaces have been entirely, or almost entirely replaced with ReferenceSource code:

System.Collections

System.Collections.Concurrent

System.Collections.Generic

System.Collections.Specialized

System.ComponentModel

System.ComponentModel.Design

System.Diagnostic.Contracts

System.Linq

System.Linq.Parallel

System.Text.RegularExpressions

System.Runtime.CompilerServices

System.Threading.Tasks

Partial changes:

System: ArraySegment BitConverter Boolean, Byte, Char, Decimal, Int16, Int32, Int64, SByte, UInt16, UInt32, UInt64, Convert DateTime, Decimal Guid Lazy Random TimeSpan Version

System.Collections.Generic HashSet Mostly replaced

System.Diagnostics.Contracts

System.Globalization Entire calendar stack DaylightTime TextInfo (replaces text categorization tables, replaces it with .NET which is half the size)

System.IO BufferedStream Stream MemoryStream StreamReader, StreamWriter, StringReader, StringWriter, TextReader, TextWriter

System.Linq.Expressions DynamicExpression, ExpressionVisitor

System.Net Cookie, CookieCollection, CookieContainer, FtpWebRequest WebClient

System.Text Bring the non-code page encoders

System.Threading (about 60% replaced)

Also the System.Numerics has been updated to use ReferenceSource (it used an older Microsoft open sourced version of the library in the past)

Garbage Collector

The Xamarin performance team has been fine tuning Mono’s SGen garbage collector.

Dropped Support for Old Frameworks

Reference Assemblies

We no longer build the reference assemblies for the .NET 2.0, .NET 3.5 or .NET 4.0 APIs, we now ship binaries of the reference assemblies (API contracts, without any actual executable code in them).

Mono will now only build the .NET 4.5 assemblies as well as the mobile-based profiles.

Note: You can still run assemblies compiled for earlier .NET profiles on Mono, there’s no need to recompile them (they’ll just run on the .NET 4.5 assemblies instead).

Npgsql

Mono no longer distributes the Npgsql driver. Developers that need it will be better served by using the actively maintained Npgsql driver from this site:

https://github.com/npgsql/npgsql

EntityFramework

The version of EntityFramework that we shipped had not been updated in a long time, and users are currently getting EntityFramework with NuGet.

Other Features

Added LLDB scripts to assist developers debugging the runtime with LLDB

MonoIO method and classes now uses SafeHandles

System.Net.NetworkInformation implements more features on more platforms

Fine tuning

We now inline copies of structures up to eight machine words, up from the previous five. Values larger than that still call memcpy to complete the operation.

We now support returning floating point structures by value and can better pack floating point structures.

LLVM is now given more lattitude to inline generated code.

More methods can be compiled with LLVM on ARM. This helps many methods that passed large structures as parameters.

All atomic methods in the framework are now recognized by the JIT as intrinsics and are inlined as specialized code on platforms that support it. This includes all methods on Interlocked and Volatile , as well as the MemoryBarrier , VolatileRead , and VolatileWrite methods on Thread .

On x86-64, Thread.MemoryBarrier is now implemented with mfence instead of lock add rsp, 0 . Also, Interlocked.Exchange is now implemented with xchg [dst], val instead of the overly expensive lock cmpxchg [dst], val loop we previously emitted.

For atomic methods with acquire/release semantics, we now emit memory barriers with those semantics instead of the overly strong sequentially consistent kind.

The Enum.HasFlag method is now significantly faster for the most typical usage pattern, which is a.HasFlag (b) where a and b are the exact same type. We transform such calls to an actual bitwise AND and skip all the heavy reflection normally done in the method. This is about 60x faster than before. Additionally, the regular implementation of the method which is only used for rare/pathological cases is now 4x faster than before.

The JIT now avoids emitting pointless move opcodes when the destination register is the same as the source register.

The runtime now supports performing calls directly to some internal calls (those that are known not to raise exceptions). This eliminates the overheads of wrapper methods, both a performance and memory usage benefit.

When precompiling your assemblies, you can use the “direct-calls” option to enable this feature.

monop tool

The monop tool now uses IKVM.Reflection to load assemblies, so it will work with foreign mscorlibs. In addition the -xi and -xa flags can be used to search types in the Xamarin.Android and Xamarin.iOS frameworks.

musl libc

There is now rudimentary support for building Mono with the musl libc on Linux. To do this, pass --disable-boehm --without-sigaltstack to configure .

Mac Changes

System.Net now supports Mac’s .pac proxy configurations.

C99 switch

The runtime now requires a compiler with C99 support. For Windows users, this means that Visual Studio 2013 is now required to build Mono. Cygwin or MinGW users should not be affected by this change. Similarly, compilers on most Unix platforms have supported C99 for a long time.

Bug Fixes

14277: Stepping in static constructor exits

17944: mono: mini-amd64.c:492: amd64_patch: Assertion `0’ failed.

18800: IndexOutOfRangeException when MultipartFormDataContent filename value contains whitespace

19334: BeginWrite failure at System.Net.Sockets.NetworkStream.BeginWrite

19823: InvalidOperationException in ServicePoint.RemoveConnectionGroup

19881: ProductInfoHeaderValue fails to parse User-Agent string without version

20764: WebMessageFormatter crashes with void return type OperationContract

21072: DataContractSerializer does not serialize enum flags the same as .net 4

21172: text field type nvarchar(max) is truncated to 4000 chars

22501: XmlSchema.Read raises InvalidElementError for certain inputs which work fine in MS.NET

23242: Null reference exception occurs after the call to Int.ToString() from multiple threads

23401: Sgen’s marksweep-conc fails under load test

23771: UTF8 Decoder’s Convert does not keep internal state between calls when ‘flush’ parameter is false

23808: HMACSHA256 default ctor creates 64-bit key, expected 64-byte

23966: HttpClient.GetStreamAsync behaves differently from .Net

23981: Some [Assembly*] attributes are not “compiled” correctly in the PE files

23987: Unable to debug on Lollipop

24084: sgen assert in sgen_obj_get_descriptor () when frequently allocating with FormatterServices.GetUninitializedObject()

24086: Runtime test - TestDaylightSavingsTime failed for Casablanca (Western European Standard Time)

24172: C# Invalid code generation with nested types in namespace

24221: Sorting of large structs with wrong result.

24300: Bad Xml produced by XmlSerializer writing on XDocument

24342: Debugger race condition

24419: Synchronized static methods of generic classes lock on the open type instead of the closed one

24431: CultureInfo constructor error message decimal and hex lcid should be different

24452: yield statement used in foreach returns first record only

24511: mcs hangs during compile

24537: mcs ignores missing bracket

24577: Fatal Unhandled Exсeption: System.FormatException

24588: __clear_cache in mini-arm.c not supported in gcc toolchain

24638: Crash occurs when passing an array of objects to a COM method

24675: Mono C# parser encounters a CS0584 internal compiler error when loading a constant from a legal dll

24704: System.Net.Http.HttpClient PostAsync ignores timeout if webproxy isn’t accessible

24720: Crash when freeing COM callable wrappers

24757: LogicalCallContext not flowing with async calls

24775: List.ForEach does not throw InvalidOperationException when collection was modified

24784: Multiplication when passing optional parameter is now failing to compile

24785: System.Net.Http, need to escape more RFC characters

24935: Dynamic property is case sensitive

25009: Mono crash when stopping a debug session

25050: DST transition bug

25059: StructLayout.Pack <= 16 throws TypeLoadException at runtime

25086: Embed assemblies in native code option causing sample build failures on windows

25087: System.Uri constructor throws an exception when parsing an HTTP URI with a username or password that contains certain escaped characters

25095: Struct w/nested structs as return value from P/Invoke is incorrectly marshalled on x86_64/OSX

25106: Microsoft.Win32.Registry.GetValue() requires write permission on Windows

25107: Compiled method names differ between 32 and 64 bit builds

25132: SafeHandle always called with Disposed(true)

25165: Bad code and async/await in a Task causes “Internal compiler error”

25213: HttpClient.SendAsync throws out of memory exception on large files

25224: stack overflow after printfn something

25357: .mdb has invalid scopes

25358: Invalid mdb scopes for variables

25498: System.IO.SynchronizedStream does not call Close on wrapped Stream

25544: Documentation on method with co/contravariant parameters raises CS1569: Error generating XML documentation

25629: nunit-console leaves zombie processes in mono 3.12 vs proper behavior in prior versions (3.10)

25631: Mono throws OutOfMemoryException on Ubuntu but not OSX or Windows

25646: Microsoft_FSharp_Core_LanguagePrimitives_HashCompare_GenericCompare causes assertion

25664: FieldInfo.GetValue causes segmentation fault when field is of pointer type

25679: Memory leak and buffer overflow in get_gsharedvt_type()

25690: * Assertion: should not be reached at icall.c:1902

25720: Runtime crashing when evaluating System.Diagnostics.Process.HasExited property

25798: LessThanOrEqual wrong result for nuint type on 32bit platform

25808: DataContractJsonSerializer cannot deserialize array to IEnumerable<T>

25821: Generic symbol names exported from libmono

25850: SafeHandle.Close() is not idempotent.

25891: Custom marshaler broken in 8.6

25895: Wrong exception is thrown when calling System.Globalization.CharUnicodeInfo.GetNumericValue(string s, int index) with invalid index

25928: Barrier constructed with 0 participants will hang on AddParticipant

26008: Wrong DST when TimeZoneInfo has floating date rules.

26033: Set next statement(CMD_THREAD_SET_IP) + stepping doesn’t work as expected

26109: System.Net.Http.Headers.RangeHeaderValue fails to parse with large byte range

26219: Result of cast from double to int is different on Mono amd64 than on .NET and Mono x86

26346: Full AOT crash: Instructions.cpp:281: void llvm::CallInst::init(llvm::Value *, ArrayRef<llvm::Value *>;, const llvm::Twine &):

26384: Assembly.GetType() fails to parse type names containing commas

26412: ConstructorInfo.ContainsGenericParameters behaves differently to MS.NET

26436: .mdb generated on Windows and used on *nix fails on some sdb commands

26688: RFE: Update valgrind headers

26736: C# async lambda with nested lambda and “goto” statement causes compiler to crash.

26753: Project compiles in Visual Studio but not in Xamarin Studio.

26840: InternalErrorException on specifying Optional attribute

26842: Support reproducible builds

26892: mcs generates CS0254 error for cast in fixed statement

27001: Using alias not in scope for nested class inheritence

27020: Compiling class with “fixed” member against System.Runtime.dll contract fails with StructLayoutAttribute not accessible

27036: Adding the user-agent header to HttpClient object throws a System.FormatException: Invalid format.

27086: Writing in asynchronous FileStream adds 0 bytes at the beginning of the file

27352: HttpRequestMessage: adding Accept header with multiple values fails

27386: HttpClient doesn’t honor BaseAddress with the Get*Async methods

27525: C#6 interpolated string raises NotImplementedException: CloneTo during compilation

27533: C#6 interpolated string raises Internal compiler error during parsingSystem during compilation

27597: csharp REPL on Windows doesn’t accept any input

27697: Debugger crash: error: * Assertion at ../../../../../mono/mono/mini/debugger-agent.c:2475, condition `tls’ not met

28098: After running a mono process the shell no longer shows input chars

28172: 3.12.1.

28196: FlowAnalysis issue with out parameter and finally and delegate containing a return

28211: Getting “error MT3001: Could not AOT the assembly” When Building for Device

28213: Xamarin Studio on OSX fails to compile where Visual Studio 2013 succeeds

28292: Internal compiler error when an interpolated string is too long

28293: Unexpected symbol error when two interpolated strings are used with the ternary operator

28383: Marshal.AllocCoTaskMem(0) incorrectly returns null

Runtime/JIT

Fixed some cases where some runtime-internal memory barriers would not actually be emitted because the barrier kind field was being set to nonsensical values. Note: This did not affect Thread.MemoryBarrier .

. Fixed memory ordering of Interlocked.CompareExchange to be sequentially consistent instead of combined acquire/release when using LLVM.

to be sequentially consistent instead of combined acquire/release when using LLVM. Fixed some atomic intrinsics not getting a stack type set, leading to issues in the method-to-ir code generation pass.

code generation pass. Fixed marshalling bug when invoking differently typed delegates obtained through Marshal.GetDelegateForFunctionPointer with the same native function pointer.

with the same native function pointer. Dropped old Mono JIT conventions for saving registers on function entry.

Optimized allocation of small objects (1% speed improvement to Roslyn compiling our mscorlib)

Contributors

Bill Seurer, Michael Matz, Aetf, Alex J Lennon, Alex Rønne Petersen, Alex Soto, Alexander Kyte, Alexander Köplinger, Alexis Christoforides, Alistair Bush, Alistair Leslie-Hughes, Atsushi Eno, Ben Woods, Bill Seurer, Brendan Zagaeski, Chris Hubbard, Craig Minihan, Crisdut, Damien Daspit, Dave Curylo, David Karlaš, David Karlaš, Eberhard Beilharz, Etienne CHAMPETIER, Fritz Elfert, Guillaume Turri, Henrik Feldt, Jb Evain, Jeffrey Stedfast, Jim Westfall, Jo Shields, Joao Matos, João Matos, Jon Purdy, Jonathan Pryor, Jonathon Rossi, João Matos, Kai Ruhnau, Kenneth Pouncey, Leonid Shalupov, Liam McSherry, Lluis Sanchez, Ludovic Henry, Marc-Andre Ferland, Marcos Henrich, Marek Habersack, Marek Safar, Marius Ungureanu, Mark Probst, MarkS, Martin Baulig, Martin Thwaites, Mauricio Faria de Oliveira, Michael Matz, Miguel de Icaza, Mike Morano, Mirco Bauer, Neale Ferguson, Paolo Molaro, Radek Doulik, Reuben Bond, RiJo, Robin Neatherway, Rodrigo Kumpera, Rolf Bjarne Kvinge, Ryan J. Melena, Ryan Melena, Sebastien Pouliot, Sergey Odinokov, Stephen McConnel, Stone Gislason, Thomas Petazzoni, Ungureanu Marius, Vincent Povirk, Vlad Brezae, Vladimir Kargov, Zoltan Varga, fquiroz01, irodriguez, zevane.