Comment made by: alexyakushev
I've taken a stab at the implementation suggested by (link: ~alexmiller). The attached patch uses getComponentType instead of string magic, and introduces the following improvements compared to the first patch:
- aset is now supported as well. All indices but last are unrolled into {{RT.aget}} calls and the outermost call is expanded to {{RT.aset}}.
- If the inlined version can't resolve the type of the array at any point, then, instead of unrolling into N {{RT.aget}} calls (which will cause N compiler reflection sites) it will generate an invocation of the non-inlined {{aget}} call that will use {{Array.get}} (which is faster).
On the downside, multi-arity calls to {{aset}} now trigger compiler reflection where it used to be {{Array.set}}. I wonder if it makes sense to smoothen out those corners too, or whether it's actually better that reflection in such cases is more visible (shows in compiler warnings).
I also attached the REPL log of validation examples (uses clj-java-decompiler). It would be nice to convert it into tests, but I don't yet know how.
On a side note, I had to use a hack {{((var aget) ...)}} to force the non-inlined version to be called. Can't say I like it much, but I haven't come up with anything better. Another way would be to separate non-inlined version into a separate private function, but I don't want to add even more Vars to core namespace.