Skip to content

Cache custom marshaling behavior for comparisons #4

@monkey0506

Description

@monkey0506

Describe the issue

Because custom marshaling behavior is built into the generated delegate types, it is necessary to compare the relevant method arguments against the generated types' marshaling behaviors. As of right now, this is done with inline new MarshalAsAttribute statements. As the number of type comparisons increase, this will create GC pressure and likely cause performance issues when creating a new INativeAction/INativeFunc instance.

Proposed solution

Rather than generating a series of inlined new MarshalAsAttribute statements, a single look-up table could be defined in the generated source files. This can be cross-referenced for any case where the custom marshaling behavior is the same. For example, the return type marshaling is kept as a separate parameter, so any instances that share the same constructor arguments for MarshalAsAttribute could reference a single static object. Similarly, the arrays used for parameters' marshaling could be cached and shared, and the individual objects in those arrays could be cached as well.

Because every use-case is known at compile-time, the number of allocations can be minimized and remove the GC pressure of constantly creating new objects at each instantiation. In the generated code, this might look something like this:

file static class MarshalInfo
{
    public static readonly MarshalAsAttribute[] Attributes = { ... }; // array filled in by source generator with references to each MarshalAsAttribute
    public static readonly MarshalAsAttribute?[][] ParameterAttributeArrays = { ... }; // filled in by source generator with references to each unique combination of MarshalAsAttribute[]
}

Then the NativeGenericDelegateInfo object (in the generator) could simply hold a reference to the runtime object or array needed for the comparison in MarshalInfo.Equals (method call generated at the end of the NativeGenericDelegateInfo constructor), rather than creating new objects.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions