Description
If exception marshaling is enabled, we redirect calls to the objc_msgSend
family of functions to our own wrappers that sets up exception handling for Objective-C. Since these handlers are generic (one per objc_msgSend
function), they have to do significant work to calculate the stack size for the function call.
We can generate specialized wrapper functions instead, but it's currently hardcoded for a few specific scenarios (i386 with exception marshaling disabled): https://github.com/xamarin/xamarin-macios/blob/2b3ef0e1832cc71adc91eb995cbc7099c123cbe8/tools/common/Application.cs#L101-L112
The idea is to make it possible to enable the generation of these wrapper functions by passing a command-line argument to mtouch/mmp (--optimize=generate-specialized-pinvoke-wrappers
for instance).
Numbers for this very simple sample:
void RunTest ()
{
Stopwatch stopwatch = Stopwatch.StartNew ();
const int Count = 1000000;
for (int i = 0; i < Count; i++) {
var x = RetainCount;
}
stopwatch.Stop ();
Console.WriteLine ($"{Count} iterations in {stopwatch.ElapsedMilliseconds}ms");
}
- Release build (default): 1000000 iterations in 22ms
- Release build with --marshal-objectivec-exceptions=throwmanaged: 1000000 iterations in 235ms
- Release build with --marshal-objectivec-exceptions=throwmanaged and pinvoke wrappers: 1000000 iterations in 22ms
So the effect of exception marshaling is basically nil when generating these invoke wrappers.