Граф коммитов

7 Коммитов

Автор SHA1 Сообщение Дата
Rolf Bjarne Kvinge 7728c4cd19 [registrar] Use metadata tokens instead of strings to find types and methods. (#1085)
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% |
2016-11-01 14:34:56 -04:00
Rolf Bjarne Kvinge 94485580b5 Use ExceptionDispatchInfo to keep stack traces when unhandled exceptions are marshaled. Improves bug #45742 a bit. (#1040)
Example code:

	public override void ViewDidLoad ()
	{
		throw new Exception ("USELESS");
	}

Current output with unhandled exceptions that are marshaled:

    Unhandled Exception:
    System.Exception: USELESS
      at (wrapper managed-to-native) AppKit.NSApplication:NSApplicationMain (int,string[])
      at AppKit.NSApplication.Main (System.String[] args) [0x00041] in /work/maccore/master/xamarin-macios/src/AppKit/NSApplication.cs:98
      at UselessExceptions.MainClass.Main (System.String[] args) [0x00007] in /Users/rolf/Downloads/filed-bug-test-cases-master/Xamarin/bxc45742/Main.cs:10
    [ERROR] FATAL UNHANDLED EXCEPTION: UselessExceptions.CustomException: USELESS
      at (wrapper managed-to-native) AppKit.NSApplication:NSApplicationMain (int,string[])
      at AppKit.NSApplication.Main (System.String[] args) [0x00041] in /work/maccore/master/xamarin-macios/src/AppKit/NSApplication.cs:98
      at UselessExceptions.MainClass.Main (System.String[] args) [0x00007] in /Users/rolf/Downloads/filed-bug-test-cases-master/Xamarin/bxc45742/Main.cs:10

Note how the managed frame where the exception was thrown does not show up.

This is because we technically catch exceptions when marshaling them, and then
later we call mono_raise_exception to raise the same exception. Unfortunately
that leads to overwriting the initial stack trace, and we end up with a stack
trace that does not include the location where the original exception was
thrown.

So instead of calling mono_raise_exception to rethrow the same exception, we
use ExceptionDispatchInfo, which is able to capture the stack trace for both
the original exception and the new exception, producing the following output:

    System.Exception: USELESS
      at UselessExceptions.ViewController.ViewDidLoad () [0x0000c] in /Users/rolf/Downloads/filed-bug-test-cases-master/Xamarin/bxc45742/ViewController.cs:27
    --- End of stack trace from previous location where exception was thrown ---
      at (wrapper managed-to-native) AppKit.NSApplication:NSApplicationMain (int,string[])
      at AppKit.NSApplication.Main (System.String[] args) [0x00041] in /work/maccore/master/xamarin-macios/src/AppKit/NSApplication.cs:98
      at UselessExceptions.MainClass.Main (System.String[] args) [0x00007] in /Users/rolf/Downloads/filed-bug-test-cases-master/Xamarin/bxc45742/Main.cs:10
    [ERROR] FATAL UNHANDLED EXCEPTION: UselessExceptions.CustomException: USELESS
      at UselessExceptions.ViewController.ViewDidLoad () [0x0000c] in /Users/rolf/Downloads/filed-bug-test-cases-master/Xamarin/bxc45742/ViewController.cs:27
    --- End of stack trace from previous location where exception was thrown ---
      at (wrapper managed-to-native) AppKit.NSApplication:NSApplicationMain (int,string[])
      at AppKit.NSApplication.Main (System.String[] args) [0x00041] in /work/maccore/master/xamarin-macios/src/AppKit/NSApplication.cs:98
      at UselessExceptions.MainClass.Main (System.String[] args) [0x00007] in /Users/rolf/Downloads/filed-bug-test-cases-master/Xamarin/bxc45742/Main.cs:10

Incidently this is how Xamarin.Android does it [1].

[1]: 9387f2fe16

https://bugzilla.xamarin.com/show_bug.cgi?id=45742
2016-10-27 20:03:11 +02:00
Rolf Bjarne Kvinge 2d28e24837 [runtime] Handle any exceptions whenever we return from managed code. 2016-06-08 20:05:54 +02:00
Rolf Bjarne Kvinge 71f4d78b18 [runtime] Generated binding wrappers that catch ObjC exceptions are supposed to always convert to managed exceptions. (#133) 2016-06-06 14:33:37 +02:00
Rolf Bjarne Kvinge ac5ff5e321 [runtime] Replace xamarin_try_get_nsobject with xamarin_has_nsobject.
Removes one usage of ObjectWrapper, since we don't actually need
the return value, we just need to know if an object exists.
2016-05-26 17:47:10 +02:00
Rolf Bjarne Kvinge 1f1f6991a3 Implement support for exception marshalling. 2016-05-17 11:23:48 +02:00
Rolf Bjarne Kvinge ac418df815 Build our runtime. 2016-04-24 14:47:24 -04:00