* Convert it into a MM8027/MT8027 error (with documentation).
* Add information about the selector and managed method that triggered the error.
Now the problem reported in issue #4254 shows up as:
> ObjCRuntime.RuntimeException: Failed to marshal the Objective-C object 0x7f8080412810 (type: UIView). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'UIKit.UIView&' does not have a constructor that takes one IntPtr argument).
> Additional information:
> Selector: popoverController:willRepositionPopoverToRect:inView:
> Method: UIKit.UIPopoverController+_UIPopoverControllerDelegate.WillReposition(UIKit.UIPopoverController, CoreGraphics.CGRect ByRef, UIKit.UIView ByRef)
instead of just:
> ObjCRuntime.RuntimeException: Failed to marshal the Objective-C object 0x7f8080412810 (type: UIView). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'UIKit.UIView&' does not have a constructor that takes one IntPtr argument).
which makes it much easier to understand, track down, and fix/work around,
both for customers and ourselves.
* [tests] Build the native test library for macOS and create a binding project for it.
Also add the new binding project to the xammac and link all XM test projects,
which allows us to stop excluding tests that require the native library and
the corresponding bindings.
* [tests] Include more tests in xammac_tests.
* [tests] Correctly ignore the ObjC exception tests in release mode.
Use metadata tokens instead of strings to find types and methods.
This makes the code to find methods more compact (a lot less strings in the
executable, and additionally in most cases a compact representation (32-bit
integer) of the corresponding metadata token and additional information can be
used, which results in less executable code (fewer parameters to methods,
etc)), resulting in smaller executables.
Size savings are around 200kb for dont link apps, and 20-60kb for linked apps
(this obviously varies a lot depending on how much has to registered by the
registrar).
| | Before | After | Diff |
|----------------|--------------:|--------------:|------------------:|
| dontlink/32bit | 102.810.144 | 102.609.456 | -200.688 = -0,20% |
| dontlink/64bit | 107.420.576 | 107.221.792 | -198.784 = -0,19% |
| linksdk/32bit | 40.957.296 | 40.936.864 | -20.432 = -0,05% |
| linksdk/64bit | 43.113.136 | 43.093.936 | -19.200 = -0,04% |
| linkall/32bit | 38.410.032 | 38.348.288 | -61.744 = -0,16% |
| linkall/64bit | 40.315.200 | 40.267.344 | -47.856 = -0,12% |
Additionally I've removed the `lazy_map` dictionary, which we populated at
startup and was used to map between Class instances and the corresponding
managed type's FullName, and instead iterate over a native array of Class ->
metadata token mappings whenever we need to look up the managed type for a
certain Class instance.
This is slightly slower for each type we need to look up (for a non-linked app
there might be a 2000-3000 entries in the native array, which would be
iterated instead of using a hashtable lookup), but it's only done once per
type and there's a significant startup memory improvement.
For a non-linked test app I get the following using the Xamarin profiler:
| | Before | After | Diff |
|-------------------|--------:|--------:|----------------:|
| Memory allocated | 2,8 MB | 2,4 MB | -0,4 MB = -14 % |
| Objects allocated | 43678 | 38463 | -5215 = -12 % |
| Private bytes | 26,6 MB | 24,4 MB | -2,2 MB = -8,3% |
| Working set | 26,6 MB | 24,4 MB | -2,2 MB = -8,3% |
* [tests] Remove Classic SDK tests.
* Remove XI/Classic support.
This also means we can remove support for the legacy registrars.
* [monotouch-test] Remove legacy registrar tests.
* [tests/mtouch] Remove Classic tests (and legacy registrar logic).
* [tests/scripted] Fix tests to reference Xamarin.iOS.dll.
https://bugzilla.xamarin.com/show_bug.cgi?id=44399
We did not fully support passing null to name and objectToObserve in
CFNotificationCenter::AddObserver an ArgumentNullException was thrown
The use case of sending null to both name and objectToObserve is to
observe all notifications posted to the notification center, this
won't work using darwing notification center, it is restricted
by apple.