On 05/13/2012 07:21 PM, Charles Oliver Nutter wrote: > On Sun, May 13, 2012 at 11:04 AM, Jochen Theodorou<blackd...@gmx.org> wrote: >> I wanted to ask you of your opinion. If I am going to compile something >> like a+b-c and a,b,c are all primtives, but I won't know that the >> results will be really the primtives too, then this means I will most >> probably compile it like this: >> >> invokedynamic("minus", invokedynamic("plus",a,b), c) >> >> meaning the result of a+b will be an Object (since I won't know it is a >> primitive) and then there will be one boxing for that, just to unbox >> again for the minus and then box again for the result of the minus. If >> now the result is not supposed to be a primitive, then there won't be >> another unbox, till the next operation done with that value. > You could also encode "a+b-c" as a single invokedynamic operation, but > I guess you're looking for a general solution... > >> Now, even if the JIT is able to see through the one boxing and unboxing >> fro the result of plus, what will stay is the boxing for the result of >> the minus.... plus the many unboxing actions used when this result is >> used. Isn't that a conceptual problem? And how do others deal with that? > First of all...how are you expecting that JIT will see through the > first boxing? If the return result is going to be Object, it's going > to go into an Integer. Perhaps you are hoping for escape analysis to > get rid of it? > > If that's the case, why wouldn't the same expectation apply to the > second call? If (a+b) returns an Integer that's immediately passed > into (tmp-c) and both calls inline, in theory EA should have enough to > eliminate the intermediate. If the result of (tmp-c) is never used as > an object and never escapes, then EA should be able to get rid of that > too. > > Of course this is all assuming that EA will be working across indy > boundaries in the near future. Currently, it does not. > > In JRuby, where we have no static typing or type hints, we always do > these invocations as all reference types. We're banking on JVM helping > us out in the future, so my goal is to just use indy as efficiently as > possible and keep call protocols simple. > > A confusing point for me: in your case, where you know they're all > ints, how do you not know that + and - also return int? Can't you > determine statically that this whole expression will return a > primitive int?
I think currently Groovy allows to replace + by a method that will return everything you want. But here, I think the spec of Groovy (if it means something) should be changed to say that when your replace a method by another, the return type must be a subtype of the existing method. > >> I am asking because I was experimenting with method signatures and for >> such plus and minus methods and got mixed results. I was expecting the >> primtive versions would achieve the best results, but that was not the >> case. a plus(int, int) had worse performance than a plus(int,Integer) or >> plus(Integer,int) in some cases and sometimes it looked like >> plus(Integer,Integer) is worse, in other cases not. Well, this is >> causing me some problems. Why do I get such strange results? I would >> assume it depends on the JIT and the boxing logic it is able to >> recognize and not. > What does the assembly look like? > > In my case, passing int instead of Fixnum where possible (usually only > when a literal integer appears in the argument list) definitely helps; > I don't have to construct a Fixnum or go to a cache to get it, and on > the other side there's no type-checking required to make sure I really > have a Fixnum. The int paths should be faster than the Integer paths. > > And again remember...I don't think the JIT in u4- does anything with > the boxing coming out of these calls. It might do something on the > other side, but not across the invokedynamic call. > >> One more thing I noticed is, that if I have a = b+c, with all of them >> being int and b+c returning object, then letting the MethodHandle do the >> conversion from Object to int is actually much worse performance wise, >> than a cast to integer and calling valueOf. Shouldn't that be at least >> equal, if not fast considering that the result of b+c was first boxed >> and then is unboxed? > Perhaps doing it in the handles makes the code more opaque? Do the > non-handle way and the handle way have exactly the same logic? Object -> int is not equivalent to Object -> Integer -> int, it can be Object -> Byte -> int by example. You have to chain several calls to asType() see slide 20 of my jvm summit talk last year, http://wiki.jvmlangsummit.com/images/9/93/2011_Forax.pdf > > Bottom line here is that if you need a reference type on LHS, you'll > have to create a reference type, and we need the JVM to figure out > that it can brush that part away. > > - Charlie Rémi _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev