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.
* [runtime] Add an inner exception parameter to Runtime.CreateProductException.
This allows us to simplify code by using inner (and outer) exceptions as
a means to provide information instead of passing extra information
around in order to create decent exceptions.
One example is how we pass the selector and method name to the method
that converts from a native id to a managed NSObject instance: passing
this information is not necessary anymore if we can use two exceptions,
one for the failure to convert from an id to a NSObject instance,
wrapped in a second that tells which method/selector call ran into this
conversion problem.
* [runtime] Throw better exceptions when the dynamic registrar can't marshal something.
* [runtime] Throw a better exception when something goes wrong when trying to marshal a return value.
* [runtime] Use inner exceptions to convey failure information instead of trying to create a single exception with all we know.
* Fix merge problem.