Description
Currently each closure will get a vtable slot for the dynamic call forwarder. That forwarder takes a list of arguments and a list of named arguments. It then directly calls the target.
We want to avoid paying a code size cost for each closure in the program if there's a single dynamic call user.
I think we can instead make the vtable slot for the dynamic call forwarder contain a function that is shared among all closures that have the same closure representation.
If we do this then that shared dynamic call forwarder cannot directly dispatch to the target function, as we'll have a 1<->N relationship. Though that shared dyn call forward has access to the closure and the vtable. And since it's per-closure-representation cluster we know the layout and entries of the vtable.
That in return means that instead of directly dispatching to the target, it can inspect the number of positional arguments in the array it got and the names it got and then (indirectly) call the corresponding entry in the vtable matching that positional & name combination.
This would possibly remove the majority of dynamic call forwarder functions.
/cc @osa1