[armedbear-devel] Why does jcall use reflection?
alessiostalla at gmail.com
Sat Jan 9 00:10:07 UTC 2010
On Sat, Jan 9, 2010 at 12:28 AM, Axel Rauschmayer <axel at rauschma.de> wrote:
> I hope this is not a stupid question, but: Why does jcall use reflection?
> Doesn't ABCL compile lisp to byte code? If one could statically declare to the compiler the intended Java class, couldn't method invocations be compiled instead of being performed via reflection?
> OTOH, I don't know how ABCL handles interpretation versus compilation, so that might be an issue.
I had a talk today with Erik about this topic, so I suppose I'm
informed enough to speak ;)
To make it short: reflection could be eliminated in some cases, but
it's quite costly in terms of development effort.
The long explanation: there are several reasons. Keep in mind that
ABCL has both an interpreter and a compiler.
- In interpreted code, reflection is the only possibility.
- In compiled code:
- some method invocations through jcall cannot be resolved at
compile time - extreme example: (jcall (read) nil).
- others could be resolved. How many depends on the effort we can
put into the compiler: it could recognize only calls to a method which
literally appears in source code - (jcall (jmethod "foo" "bar") baz) -
or, by doing type inference, more cases could be discovered. The
compiler currently does nothing in that regard, except caching the
method metaobjects per call-site when possible. So in the foo-bar-baz
example above, method "bar" of class "foo" is only resolved once, at
load time, and then reused - for that particular call site.
It is dubious whether enhancing the compiler to eliminate reflection
for some jcall invocations would be worth the effort. Since Java
objects are boxed in ABCL, the compiler would need to generate code to
unbox the arguments and box the return value, and place appropriate
exception handlers. This would likely increase the size and complexity
of the generated code quite a lot. Also, I believe that to optimize a
significant number of jcall invocations we need type inference, and
that's not an easy task.
Of course, the implementation of jcall has to do the very same
boxing/unboxing, besides the reflective call itself; it is inevitably
less efficient. But I think that, unless your code is made mostly of
calls to Java methods, the difference is tolerable.
More information about the armedbear-devel