Replies: 2 comments 3 replies
-
I'm not sure I'm 100% following the approach you're describing here - or, at least, I can see a couple of possible interpretations:
There might be other interpretations depending on exactly where you're thinking of drawing the line between Python and Java. As I understand it, (1) would require a pretty radical rebuild of Rubicon. I like the idea of minimising reflection, as the JNI calls (especially the initial startup an handle caching parts) are the slowest part of the process; however, it would be a big project. I'm also not sure how (1) would work in the case of final classes; I guess we'd end up with a Facade (in the gang-of-four design pattern sense) that calls directly into Java classes. (2a) is closest to what I had in mind as the approach I'd look at if I were to take a swing at a fix for #25. There'd still be reflection (in the sense that Rubicon's existing interface would continue to be used), but there wouldn't be runtime code generation. (2b) and (2c) really only vary from (2a) in terms what is being generated. They'd both be "neater" in the sense that there's would be less source code in a project marked "DO NOT EDIT"; but it would also be more fragile and harder to debug when things go wrong - especially in the case of (2c). (3) seems very close to what we have now, except that you seem to be suggesting more of the lookup index would be on the Java side, removing the need for reflection APIs to do method lookup. I'm not entirely sure how (3) varies from the approach we have now - or, at least, I'm not sure I see how the Java-side metadata index would work. Did you have any of these specific interpretations in mind? Are you more at the "thought experiment" phase, kicking around ideas about potential options? Or have I completely missed what you're describing? |
Beta Was this translation helpful? Give feedback.
-
This was just a thought based on the premise that if you were to take the route of generating bytecode in order to implement proxies then you could go a little bit further and generate code that doesn't use reflection or primitive boxing. It is an involved project, and only worth doing if reflection can be measured to be a bottleneck. I just brought it up here in case it crops up in future. It sounds like the Java-source generation approach is the way to go now, with Chaquopy being part of the fold. It could still be possible to source-generate Java proxy classes with direct native methods and associated JNI C code to be compiled into Rubicon before release. This would be for some set of Android and JDK abstract classes that are performance critical and likely to be used in an app. Again, just a thought for the future. |
Beta Was this translation helpful? Give feedback.
-
I've been looking at the subclassing issue #25 and diving into what it would require if the bytecode generation approach was taken.
Both JVM and DEX code generation seem reasonably straightforward, but would still be large efforts in terms of time and code size. I am more familiar with JVM generation but there seem to be several Java and Python packages for DEX generation. A large part of the effort would be in creating the minimal generator required for the subclassing use case - boxing up the arguments into an array, taking care of try-catch concerns, and calling into InvocationHandler.
Some of that complexity could be avoided if the generated proxy methods were native. This would reduce or eliminate the amount of bytecode that would need to be generated and would bypass the need for reflection or argument boxing.
The native method could be "generic" in the sense that it would use va_list etc. to handle any number of arguments on the fly.
The wrinkles are:
va_list wouldn't work on Windows, which uses the stdcall calling convention for JNI.
JNI doesn't pass the context of the called method so extra metadata would be needed in the native method. This could be passed from the Java layer by a minimal wrapper method that adds an extra metadata index param before calling the native method. Or it could be implemented in the native code by generating a pool of native methods that add the extra metadata index - this would limit the number of Java methods that could be implemented/overridden.
Food for thought.
Beta Was this translation helpful? Give feedback.
All reactions