Allow code like this
```csharp
[DllImport(Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSendSuper")
static extern IntPtr IntPtr_objc_msgSendSuper(IntPtr receiver, IntPtr selector);
[DllImport(Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSendSuper")]
static extern void void_objc_msgSendSuper(IntPtr receiver, IntPtr selector, IntPtr arg);
[Export("selectedTextRange")]
public new IntPtr SelectedTextRange
{
get { return IntPtr_objc_msgSendSuper(SuperHandle, Selector.GetHandle("selectedTextRange")); }
set => void_objc_msgSendSuper(SuperHandle, Selector.GetHandle("setSelectedTextRange:"), value);
}
```
to work on the dynamic registrar since it already work with the static one.
This allows the simulators (which defaults to dynamic) to share the same code which is useful for implementing a workaround for related issue #15677.
We were trying to call the 'retain' and 'autorelease' selectors on objects
that weren't NSObjects when returning them from function calls. For some
unfathomable reason that has worked until now, but I started running into this
problem with other (unrelated) changes, so it needs to be fixed.
The fix is to not call the 'retain' and 'autorelease' selectors on
NativeObjects, instead call into managed code to either call the Retain method
on the managed NativeObject (if we're supposed to retain the return value), or
if we have to autorelease the return value, then check first if the input is
an NSObject, and only then call retain+autorelease.
* Remove ObjCRuntime.nfloat (in favor of System.Runtime.InteropServices.NFloat).
* Automatically add a reference to the System.Runtime.InteropServices.Internal
package, so that developers get the new NFloat API (with operators) we've
added post .NET 6 (but don't do this for .NET 7).
* Automatically add a global using alias for
System.Runtime.InteropServices.NFloat -> nfloat. This is not behind the
usual `ImplicitUsings` condition our other implicit usings are, because
they're off by default for existing projects, and the main target for the
global using alias for nfloat is upgraded projects.
* Automatically generate a global using alias (like above) in the generator
for all code the generator compiles.
* Update xtro entries to reference System.Runtime.InteropServices.NFloat
instead of ObjCRuntime.nfloat.
* Add a workaround for a hopefully temporary issue with .NET/CoreCLR where the
wrong runtime pack is selected otherwise (without the new NFloat API, so
nothing works at runtime).
Ref: https://github.com/xamarin/xamarin-macios/issues/13087
The deadlock goes like this:
1. Thread A holds the framework_peer_release_lock lock, and tries to lock the
refcount_mutex lock.
2. Thread B holds the refcount_mutex, and is waiting for the GC to complete
3. Thread C is trying to lock the framework_peer_release_lock while running
the GC.
The fix is in thread A, by not doing anything at all with the
framework_peer_release_lock lock locked.
The code contains extensive comments explaining the situation and the solution.
Fixes https://github.com/xamarin/xamarin-macios/issues/13066.
Co-authored-by: Chris Hamons <chris.hamons@xamarin.com>
No more leaks!
Before:
There were 205834 MonoObjects created, 205834 MonoObjects freed, so no leaked MonoObjects. (static registrar)
There were 258092 MonoObjects created, 258013 MonoObjects freed, so 79 were not freed. (dynamic registrar)
After:
✅ There were 205834 MonoObjects created, 205834 MonoObjects freed, so no leaked MonoObjects. (static registrar)
✅ There were 258100 MonoObjects created, 258100 MonoObjects freed, so no leaked MonoObjects. (dynamic registrar)
Before:
There were 258042 MonoObjects created, 235166 MonoObjects freed, so 22876 were not freed. (dynamic registrar)
There were 205804 MonoObjects created, 204219 MonoObjects freed, so 1585 were not freed. (static registrar)
After:
There were 258050 MonoObjects created, 235177 MonoObjects freed, so 22873 were not freed. (dynamic registrar)
There were 205804 MonoObjects created, 204219 MonoObjects freed, so 1585 were not freed. (static registrar)
Before:
There were 258046 MonoObjects created, 235142 MonoObjects freed, so 22904 were not freed. (dynamic registrar)
There were 205804 MonoObjects created, 204193 MonoObjects freed, so 1611 were not freed. (static registrar)
After:
There were 258054 MonoObjects created, 235172 MonoObjects freed, so 22882 were not freed. (dynamic registrar)
There were 205804 MonoObjects created, 205190 MonoObjects freed, so 614 were not freed. (static registrar)
Before:
There were 258046 MonoObjects created, 235142 MonoObjects freed, so 22904 were not freed. (dynamic registrar)
There were 205804 MonoObjects created, 204193 MonoObjects freed, so 1611 were not freed. (static registrar)
After:
There were 258054 MonoObjects created, 235172 MonoObjects freed, so 22882 were not freed. (dynamic registrar)
There were 205804 MonoObjects created, 204193 MonoObjects freed, so 1611 were not freed. (static registrar)
Before:
There were 257927 MonoObjects created, 144942 MonoObjects freed, so 112985 were not freed. (dynamic registrar)
There were 205700 MonoObjects created, 113865 MonoObjects freed, so 91835 were not freed. (static registrar)
After:
There were 257931 MonoObjects created, 235062 MonoObjects freed, so 22869 were not freed. (dynamic registrar)
There were 205700 MonoObjects created, 203983 MonoObjects freed, so 1717 were not freed. (static registrar)
* Remove a few unused xamarin_get_*_class functions.
* Make the remaining two (xamarin_get_[nsnumber|nsvalue]_type) return a
MonoType* instead of MonoClass* - that makes things slightly simpler for
CoreCLR (the MonoClass* return values from the previous functions were
always converted to MonoType*s anyway).
* Implement the xamarin_get_[nsnumber|nsvalue]_type functions.
* Make the existing mono_get_string_class use the new (and more generic)
xamarin_bridge_lookup_class method instead of the specific
xamarin_bridge_get_string_class (which can now be removed).
This makes it easier for CoreCLR. Also, at least for CoreCLR, it's unlikely to
be slower, since we'd have to compute the MONO_TYPE_* value in any
compatibility function.
This is not the fastest implementation, but it's the simplest I could come up
with, with the target of sharing as much code as possible with MonoVM. It can
be improved later if we find out it's a slow path (these functions are not in
a common code path, very few API bindings end up here).
When using the MonoVM, we compare MonoClass instances by pointer. This turns
out a bit complicated for CoreCLR, because our MonoClass instances are not
unique (there can be multiple MonoClass instances that refer to the same
type), so instead implement helper methods that do the comparison. This also
has the benefit of not requiring any memory allocations on CoreCLR.
This also meant reviewing calling code to make sure that MonoObject*s are
released when they should be, which meant reviewing every method that returns
a MonoObject*, and release the result.
Move the xamarin_create_managed_ref internal call to managed code, to ease things
with CoreCLR.
In order to preserve performance, this wasn't a straight forward port.
* monotouch_create_managed_ref used to detect if there already was a GCHandle for
a native object. To avoid a managed->native transition, this logic has now been
moved into the code that sets the GCHandle (the xamarinSetGCHandle🎏 / xamarin_set_gchandle_trampoline
code), and these methods return a value saying whether the GCHandle was set or
not.
* xamarin_create_gchandle will check the retain count to determine whether to create
a weak or a strong GCHandle for the managed object. In this particular case we
should never need to create a strong GCHandle, which means that we don't need to
check the retain count (saving a managed->native transition).
Using the new perftest (#11298), I get very similar numbers for both old code and new code: https://gist.github.com/rolfbjarne/e0fc2ae0f21da15062b4f051138679af (multiple runs). Sometimes the old code is faster, sometimes the new code is faster (although the old code tends to be the one who wins).
In any case there aren't any significant performance hits due to this change, so it should be good to go.
* Convert the GCHandles interface from 32-bit ints to pointer size types
This involves:
* Stop using some bits of the GCHandle to store extra flags, instead add an extra
field to store those flags.
* Define a INVALID_GCHANDLE constant and use it instead of 0/NULL. This is not
strictly required, but it makes the code more self-documenting.
* Define a GCHandle type (typedef'ed to void*) and change all variables and parameters
to use it instead of guint32.
* Use our own xamarin_gchandle_* methods (with pointer-sized types) that wraps
the mono_gchandle_* embedding API (which uses 32-bit types) everywhere.
* Update managed code (registrars, runtime code, etc) accordingly.
* [runtime] Make debug code compile.
* Fix typo.
* Fix signature of xamarin_create_gchandle.
Co-authored-by: Aaron R Robinson <arobins@microsoft.com>
These methods were already partially using GCHandles, so convert the parameter
using ObjectWrapper to GCHandle, and port the rest of the existing logic to
use the new helper API.
Some of the fixes done for the warnings have breaking changes. Move back
to int and ensure that we do not have any compilation errors (we are
using -Werror).
Fixes: https://github.com/xamarin/xamarin-macios/issues/7509
* [Runtime] Enable the -Wshorten-64-to-32 flag and fix all warnings.
We want to enable the -Wconversion but that will raise too many warning
for a single commit. We are enabiling one by one the flags included in
-Wconversion so that we have smaller diffs.
-Wshorten-64-to-32 adds warnings when there is a implicit conversion that
loses integer precision. We are moving all the 32 to 64 conversions to
use 64. Expecially since most of the code changed is related with sizes,
legths and params counts that are never going to be negative.
Co-Authored-By: Rolf Bjarne Kvinge <rolf@xamarin.com>
Enable the -Wsign-compare which will raise issues when a comparison
between signed and unsigned values could produce an incorrect result
and fix all the raised warnings.
It's now required to cast objc_msgSend[Super] to a function of the correct
signature, so let's do that.
Also remove the define that allowed us to use the previous behavior.
It turns out 'object_getClass' and '[obj class]' does not return exactly the
same. It seems this would have gone unnoticed (the difference would not be
important), except that it made us run into yet another Objective-C runtime
bug...
So return to the previous behavior (call 'object_getClass'), and instead call
'[obj class]' as well just before to make sure the Class instance we get back
from 'object_getClass' is initialized properly.
Now you may wonder why the return value from '[obj class]' has an effect on
the different return value from 'object_getClass', and the answer is that I
have no idea whatsoever. It works, and that makes me happy.
Fixes https://github.com/xamarin/xamarin-macios/issues/6302.