Skip to content

Improve super calls #25362

@rolfbjarne

Description

@rolfbjarne

Currently we call objc_msgSendSuper by doing something like this:

NSObject obj = ...;
objc_msgSendSuper (obj.SuperHandle, Selector.GetHandle ("..."), ...);

this is a problem, because NSObject.SuperHandle is a pointer, and the implementation has to go through some rather significant hoops to make sure:

  • The pointer always points to valid memory (which can't be managed memory, because the GC can move managed memory)
  • Is freed at some point
  • Isn't freed too early

An improvement would be to do it more like native code does it:

NSObject obj = ...;
var super = new objc_super (obj);
unsafe {
    objc_msgSendSuper (&super, Selector.GetHandle ("..."), ...);
}
GC.KeepAlive (obj);

// and where the P/Invoke is:

unsafe static extern void objc_msgSendSuper (objc_super* super, IntPtr selector, ...);

// and objc_super's ctor is:

public objc_super (NSObject obj)
{
    Handle = obj.Handle;
    SuperHandle = obj.ClassHandle;
}

This would allow the NSObject.SuperHandle code to be simplified (and even removed in XAMCORE_5_0) - or at least less optimized. In particular it would be useful to remove the classHandle field from the NSObjectData struct, so that NSObjectData's size is no more than 2 pointers, so that we can put it in the tagged memory returned by ObjectiveCMarshal.CreateReferenceTrackingHandle (a very simple solution would be somehow chuck the return value from SuperHandle into a static ConditionalWeakTable).

The plan for objc_msgSendSuper would go something like:

  • Make the NSObject.objc_super struct a top-level public type, and rename it to ObjCSuper. Also if we could make it a 'readonly ref' struct that would probably be good.
  • Update bgen to generate the new pattern.

Metadata

Metadata

Assignees

Labels

No labels
No labels
No fields configured for Feature.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions