This is computed **twice** _per instance_, when the instance is
* created: `NSObject.CreateManagedRef`
* released: `NSObject.ReleaseManagedRef`
However its (boolean) value remains identical for all instances of the same type.
This shows up as consuming a lot of time in the logs attached to https://github.com/xamarin/xamarin-macios/issues/15145
Basically two things are cached
* the selector for `xamarinSetGCHandle🎏`, which makes it 15% faster;
* some platforms, but not macOS, have an optimization for the `Selector.GetHandle` API
* the result is cached into a `Dictionrary<IntPtr,bool>`
Note that the optimizations are not specific to CoreCLR nor macOS (so they are not fixes for the CoreCLR performance regression of the above mentioned issue).
OTOH it will also help performance for legacy and other net6 (mono) platforms.
```
BenchmarkDotNet=v0.12.1, OS=macOS 12.3.1 (21E258) [Darwin 21.4.0]
Apple M1, 1 CPU, 8 logical and 8 physical cores
.NET Core SDK= 6.0.100 [/usr/local/share/dotnet/sdk]
[Host] : .NET Core 6.0 (CoreCLR 6.0.522.21309, CoreFX 6.0.522.21309), Arm64 RyuJIT
Job=InProcess Toolchain=InProcessEmitToolchain IterationCount=3
LaunchCount=1 WarmupCount=3
```
| Method | Length | Mean | Error | StdDev | Ratio |
|----------------- |------- |---------------:|-------------:|------------:|------:|
| Original | 16 | 7,729.8 ns | 212.61 ns | 11.65 ns | 1.00 |
| CachedSelector | 16 | 6,552.6 ns | 202.70 ns | 11.11 ns | 0.85 |
| CachedIsUserType | 16 | 162.0 ns | 14.86 ns | 0.81 ns | 0.02 |
| | | | | | |
| Original | 256 | 123,183.0 ns | 4,724.95 ns | 258.99 ns | 1.00 |
| CachedSelector | 256 | 104,570.3 ns | 2,029.20 ns | 111.23 ns | 0.85 |
| CachedIsUserType | 256 | 2,489.5 ns | 390.86 ns | 21.42 ns | 0.02 |
| | | | | | |
| Original | 4096 | 1,970,381.7 ns | 66,393.09 ns | 3,639.23 ns | 1.00 |
| CachedSelector | 4096 | 1,676,773.0 ns | 12,149.92 ns | 665.98 ns | 0.85 |
| CachedIsUserType | 4096 | 39,933.3 ns | 7,426.74 ns | 407.08 ns | 0.02 |
[Benchmark source code](https://gist.github.com/spouliot/42fd43e94c5a9ce90164f0f6f9b35018)
* [nnyeah] Remove NNYEAH_IN_PROCESS on IntegrationExamples.cs as it was cursed due to global caching in nuget tool install
* [nnyeah] Simplify test API
* [nnyeah] Map NSObject ctors with IntPtr to NativeHandle
- Fixes https://github.com/xamarin/xamarin-macios/issues/15120
This required a significant amount of refactoring:
- To resolve the base type of objects, we need to invoke cecil's Resolve
- Resolve requires all assemblies to be loaded in memory, whcih requires a custom resolver to find them all
- Note: This requires customer assemblies to include all non-platform dependencies to be next to the input
- This extra state prompted a refactor of Program.cs to create a tool 'AssemblyConverter' with instance variables to reduce param passing
- The ctor mapping logic is isolated to ConstructorTransforms to reduce the growth of Reworker.cs and make limited unit testing possible
- Turns out the flat removal of the platform assembly from the import list was wrong, as it caused all platform references, such as NSObject to
be resolved from System.Runtime, which is wrong. So replace in place with the new platform assembly instead.
Microsoft.Dotnet.Sdk.Internal
From Version 6.0.301-rtm.22277.2 -> To Version 6.0.301-rtm.22280.1
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
The compiled entitlements should be placed in the intermediate Hot Restart app bundle so those can be picked up by the HotRestart Codesign task. Prior to this change, entitlements set in the project wouldn't be included in the app, making things like Keychain Access fail, even though it was configured.
Fixes https://developercommunity.visualstudio.com/t/Unable-to-use-MSAL-with-locally-connecte/1573064
Microsoft.Dotnet.Sdk.Internal
From Version 6.0.301-rtm.22274.16 -> To Version 6.0.301-rtm.22277.2
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
The current directory at launch is the root directory of the app bundle. This
means that any files written to the current directory when an app is executed,
will be placed there. This becomes a problem when the app is rebuilt (and
resigned), because a valid macOS app bundle doesn't have any files in the root
directory of the app bundle, so signing fails.
We have logic to automatically crash crash reports from the app bundle, but it
turns out this is a more common problem with other types of files (and
folders), so improve the logic a bit:
* Add support for setting a property to automatically clean up everything from
an app bundle we don't think should be there (which is anything not in a
Contents/ subdirectory).
* Use the same property to add support for disabling any cleaning (we already
clean mono's crash reports by default).
* Improve detection of unwanted files to include directories inside the app
bundle, not only files.
Ref: https://github.com/dotnet/maui/issues/7353
Remove code that we needed at some point due to memory related issues. These
issues were fixed several years ago (newrefcount), so we no longer need this
code (in fact it causes problems, see #15089).
Give the full path to the symbols list file in the extension project to the
main project, so that strip can find it.
When building a solution remotely from Windows, we can't compute a relative
path between projects, because they're laid out differently on disk. This
means that we have to use full paths when passing paths between projects (such
as the path to the symbol list file).
Fixes https://github.com/xamarin/xamarin-macios/issues/15046.
I don't remember why I excluded watch apps, and it seems to work locally, so
let's see how it goes. Hopefully we'll get better diagnostics when something
goes wrong.
The files of the bundle.zip are being re-zipped inside a 'bundle' folder after signing, which is wrong since everything else is expecting the files directly inside the zip file without parent folders (as we were doing before)
Microsoft.Dotnet.Sdk.Internal
From Version 6.0.301-rtm.22263.15 -> To Version 6.0.301-rtm.22274.16
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Remove our dependency on Visual Studio. Use the 'dotnet-t4' tool instead of
invoking the t4 tool embedded in Visual Studio.
Fixes this build error after installing VS Mac 2022:
> Cannot open assembly '/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/AddIns/MonoDevelop.TextTemplating/TextTransform.exe': No such file or directory.
tput typically fails on bots (where there's no attahed terminal) with:
> tput: No value for $TERM and no -T specified
This avoids those messages in the logs.
The values for environment variables can be null (to remove said environment
variable).
Fixes this warning:
tests/dotnet/UnitTests/TestBaseClass.cs(294,100): warning CS8620: Argument of type 'Dictionary<string, string?>' cannot be used for parameter 'environment' of type 'Dictionary<string, string>' in 'Task<Execution> Execution.RunWithStringBuildersAsync(string filename, IList<string> arguments, Dictionary<string, string>? environment = null, StringBuilder? standardOutput = null, StringBuilder? standardError = null, TextWriter? log = null, string? workingDirectory = null, TimeSpan? timeout = null, CancellationToken? cancellationToken = null)' due to differences in the nullability of reference types.
- Due to https://github.com/microsoft/vstest/issues/3658 it is not possible to test code that exits the process on error
- Create a base class for nnyeah exceptions that we want to explicitly report (and not crash), ConversionException
- Move Main to Main2 and wrap it in a try/catch for this exception
This also means that we shouldn't load the linker's output. Note that we need
to check _LoadLinkerOutput even if we've already disabled the linker, because
there may be linker output from a previous (connected) build, and we don't
want to load that.
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1542438.
- 'Error while attempting to map member System.IntPtr Foundation.NSObject::get_Handle() in old assembly'
- Also fix a strange directory name created by Cache.CreateTemporaryDirectory being called from async test method