Description
Background
The Objective-C marshal feature creates reference-counted GC handles. In the Native-AOT implementation, the callbacks for these GC handles calls into C# code. This feature was implemented in #78280.
According to the rules for these sort of callbacks, the C# code cannot allocate GC memory or take locks.
Problem
The C# code currently uses ConditionalWeakTable
. This class calls RuntimeHelpers.GetHashCode
to get a hash code for object. This in turn can potentially allocate memory or attempt to acquire a lock, in violation of the rules for restated callouts.
Potential Solutions
Don't use the ConditionalWeakTable
Instead of using the ConditionalWeakTable and hoping it and every function it calls obeys the rules for restricted call outs, create a new facility that is specifically designed with these limitations in mind.
One approach is copy the approach CoreCLR uses. The extra data could be stored in the sync table entry for the object (analogous to the sync block entry in CoreCLR). Something like this:
Change ConditionalWeakTable to not allocate
Logically, if an object has never had a hash code assigned to it, it cannot have previously been inserted into a ConditionalWeakTable
. We can take advantage of this fact to avoid allocating and take locks when locking up an object. Something like this:
Request for advise
Do either of those approaches seem reasonable?