> De: "Alex Miller" <a...@puredanger.com>
> À: "Clojure" <clojure@googlegroups.com>
> Envoyé: Jeudi 23 Mai 2019 03:47:53
> Objet: Re: Use invokedynamic instead of the reflection API when possible

> Hi Rémi! Thanks for all your work on ASM and other JVM stuff over the years by
> the way.
> We have of course been poking at indy off and on over the years and there have
> been a number of experiments with it. Ghadi Shayban has probably done the most
> work on that and he probably has more useful feedback than I would on the
> technical aspects of the code.

> Based on where we are in the release cycle right now, I expect that we 
> probably
> aren't ready to engage with this today and it might be a couple months before
> we are in the meat of the next release and open to it. Some quick thoughts and
> questions though...

> 1. As with anything we work on, we don't stuff just because it's possible to 
> do
> but because it satisfies some objective that seems worth doing. I assume the
> target benefit here is performance, but is that really it? Are there other
> benefits? Are there downsides to using indy vs reflection ?

> One big thing here is that generally we expect people to remove reflective 
> calls
> in performance-sensitive code via type hints (and some people more thoroughly
> try to remove all use of reflection). Thus my expectation would be that the
> majority of users would experience no improvement or improvements only in 
> parts
> of the code that are considered not important from a performance perspective.
> If we're adding code that increases ambiguity (via having multiple invocation
> paths which might have different failure modes) without a lot of benefit to
> users, then that prioritizes this pretty far down the list for me.

yes, using indy instead of the reflection API give you better performance 
because 
- you don't have to wrap the arguments in an array 
- you generate a specialized code for each callsite, so usually you get 
inlining. 

The other benefits are cleaner bytecode and less public API entrypoints, you 
have only one public API entry point per bootstrap method and not one per 
method call so you can change the logic and still be binary compatible. 

The "beauty" of this patch is that it doesn't add another failure mode, if at 
runtime an error occurs, instead of propagating the error and creating another 
way to get errors, it fallbacks to call the reflection API so from a user POV, 
you only get an error from the reflection API. And given that indy is not 
visible in the stack trace, you get exactly the same error with exactly the 
same stack trace. 

> 2. You mentioned the caller sensitive stuff - can you point at some resources
> about what those are? I guess those are calls checking security policy, etc?

A caller sensitive method is a method calling Reflection.getCallerClass() to 
get the caller class usually for doing a security check but it can be because 
the semantics of the method need it (get the caller class of a Logger by 
example). 
The MethodHandle API can not call those methods because internally it works by 
inserting a kind of trampoline between the invokedynamic and the method called, 
so the called method will see the trampoline code instead of the real caller 
when asking for the caller class. It doesn't help that the trampoline code is 
in java.lang.invoke which is a privileged class. 

> 3. We did some work in the last release to avoid reflective calls to
> module-private methods, by modifying our reflective search to prefer 
> interfaces
> or classes that are module accessible. Does module accessibility affect indy
> calls as well?

Modules are not an issue with indy, when an indy invocation calls the bootstrap 
method, it calls it with a Lookup object (MethodHandles.Lookup), this Lookup 
object represent the caller class and so you have the same right as if you were 
inside the caller class. 

> 4. Clojure has very few compiler / RT flags (and it's most common to use none 
> of
> them), and that's pretty intentional. Ideally we would not want a
> clojure.compiler.emit-indy flag but maybe you added this just to make the new
> work switchable.

yes, so i can compare with or without indy. Also indy is not supported by 
GraalVM native-image tool. 

> 5. We are somewhat sensitive to trying to make AOT-compiled code work with 
> later
> Clojure runtimes as much as possible (we don't guarantee binary compatibility
> but we have a very good track record here and try to never break that
> expectation). As such, we generally never change signatures in RT or Reflector
> or other important interfaces and make only additive changes. I think this
> patch is additive in that way, so that's good, but would want to carefully
> consider the new publicly accessible methods in Reflector (as we'd be
> supporting them forever), like the change in toAccessibleSuperMethod (which 
> I'm
> not sure is needed?).

oops, blunder, it's not needed. 

> There are other imo far more interesting possible uses for indy in places 
> where
> we care a great deal about performance and those are places where I would 
> place
> a lot higher priority. Ghadi, in particular, has investigated options for
> lazy-initing vars which could have a noticeable impact on startup performance
> while minimizing the effect on subsequent calls like other approaches that 
> have
> been tried. Anyways, he can probably chime in on that more.

Rémi 

> Alex

> On Wednesday, May 22, 2019 at 6:16:58 PM UTC-5, Rémi Forax wrote:
>> Hi all,
>> now that Clojure is compatible with java 8, it can use invokedynamic where it
>> makes sense, i.e. when the compiler has no information to generate directly 
>> the
>> call in bytecode, instead of using the reflection API.

>> In fact, it's a little more complex than that,
>> - you can not fully replace all calls to the reflective API to use 
>> invokedynamic
>> instead, because you have restriction on the methods you can call (you can 
>> not
>> call a method annotated with @CallerSensitive for security reason) and
>> - using the method handle API doesn't necessary means that the calls will be
>> faster than using the reflection API if the JIT is not able to inline the
>> calls.

>> So the idea of the patch is to always generate invokedynamic at compile time 
>> but
>> at runtime to use the methodhandle API if there is a good chance that the 
>> call
>> will be inlined and fallback to call the Reflector API otherwise.

>> Obviously, i've not read how to contribute before writing the patch, so the
>> patch is currently available on github
>> [ https://github.com/clojure/clojure/pull/85 |
>> https://github.com/clojure/clojure/pull/85 ]

>> So now that i've read how to contribute, i think the first question to ask 
>> is:
>> does it make sense to allow the Clojure to use invokedynamic ?

>> regards,
>> Rémi

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> [ http://groups.google.com/group/clojure?hl=en |
> http://groups.google.com/group/clojure?hl=en ]
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email
> to [ mailto:clojure+unsubscr...@googlegroups.com |
> clojure+unsubscr...@googlegroups.com ] .
> To view this discussion on the web visit [
> https://groups.google.com/d/msgid/clojure/75e34ba0-995d-4e70-9fca-b031d844ec1a%40googlegroups.com?utm_medium=email&utm_source=footer
> |
> https://groups.google.com/d/msgid/clojure/75e34ba0-995d-4e70-9fca-b031d844ec1a%40googlegroups.com
> ] .
> For more options, visit [ https://groups.google.com/d/optout |
> https://groups.google.com/d/optout ] .

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/1918664367.1783746.1558621516012.JavaMail.zimbra%40u-pem.fr.
For more options, visit https://groups.google.com/d/optout.

Reply via email to