added a comment - - edited
I've taken a stab at the implementation suggested by Alex Miller. 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.