I think this also relates to clojure startup time. Perhaps we attempt a clojure-side compilation flag that solves (or makes progress towards) both issues at AOT time?
meaning when this flag is in effect the clojure compiler generates different byte code and this byte code both starts up faster and works with graal native without needing --initialize-at-build-time.
@chris441 do you have any concrete ideas of what can be done differently?
Not without more careful consideration I do not.
what Clojure does in static initializers is resolve vars, load classes, etc.
delaying the class loading to run time won't work in a native image
I will look a lot more closely; I just know those are two related things and my profilers always show var initialization as one of the startup issues so somehow compiling that data down into something perhaps more concrete that loads faster is an interesting issue that seems related.
Also interesting for dalvik.
I know this is an area smart people have looked at before.
delaying var initialization to build time will make native images slower to start up right?
I don't want to delay anything, I want AOT to produce data as a side effect that can be quickly loaded to initialize vars during runtime initialization.
ok, but now these are are already initialized in the image heap, so that work has already been done when starting the image
Exact opposite of delaying.
My point is: moving work from build to run time makes things slower
Well, for example in your javap above:
const__0 = RT.var("clojure.core", "println");
Yes, I agree and that is not what I am suggesting. const_0
being initialized to a static class instance in your example above would make things faster as it would bypass the RT.var mechanism.
right
it could directly reference the AOT-ed class which represents the println var right?
Yes, in this case. You also have the case where something is initialized via a complex function that produces a persistent datastructure and in this case the data can be saved in resources and found via a hashtable lookup or straight array lookup in constant time eliding the generating code. I haven't looked at this in huge depth but for instance I was extremely careful with dtype-next and it still takes some time even after an AOT run to pull in, for instance, the ND system via require. This is a solvable problem.
My thought is more of the form move --initialize-at-build-time into the clojure compiler and allow anything that it did in the graal vm system to be done during the AOT step. Then --init-at-build-time should be a noop if done during graal vm compilation.
As clojure.core is AOT-ed by default anyway, I guess Compiler could be instrumented in such a way that it can reference these classes directly when generating more code. For core vars only it would already be a win
This is complicated by the fact that bytecode files aren't general data storage mechanisms (at least as far as I know) which means you need some level of sidecar file generated at build time for pure data.
The Compiler could keep track of what vars map to which classes
It would be nasty and error prone. Definitely a YMMV pathway but with time it could work well.
If it opened up both simpler Graal native and more dalvik development that would IMO be a very solid win worth real invesment.
Well, I guess if nubank agrees it may be worth real invesment 🙂.
What problems does Dalvik currently have with Clojure?
I'm seeing that Dalvik is now replaced with something else
maybe just a detail. Does ART (Android Runtime) interpret Java bytecode directly?
I am referring to this article:
Interesting article, thanks for sharing