On 05/24/2012 10:38 AM, Jochen Theodorou wrote: > Am 23.05.2012 23:33, schrieb Rémi Forax: >> On 05/23/2012 07:50 PM, Jochen Theodorou wrote: >>> no one helping me on the assembly analysis? >> Wow, you have generated the biggest fib function I have ever seen. >> >> About the bytecode you generate, as you said you have to remove >> $getCallSiteArray() because it seems it does some side effects >> so the JIT is not able to remove it. > the first time an array is generated, later nothing happens anymore... > but yes, this has to go. [...] > the method signature is (I)I, it is called with Object in the body, > because I cannot ensure that x-1 and x-2 will return an int. Since I > cannot know for sure that fib(I)I is called, the result of the recursive > fib call is seen as Object. All I know for sure is that the result of > "fib(x-1)+fib(x-2)" will be converted to an int later and will cause an > exception if the conversion is not possible. But that is the result of > the plus, thus you don't exactly need a compatible return type for fib. > In for example: > > int fib(int x) { > if (x<2) return 1 > this.metaClass.fib = {int i -> i==1?"Forax":"Remi "} > String.metaClass.plus = {String b -> delegate.length()+b.length()} > return fib(x-1)+fib(x-2) > } > assert fib(3)== 10 > > I replace fib inside fib with, well it returns a String, but signature > wise I replace it with a method returning Object. String is not > compatible with int. And it does not lead to an exception because I also > replace String#plus with a version that simply returns the added length > of both Strings. So fib(3) will call fib(2) and fib(1), which has the > results "Remi " and "Forax". Then I call plus on those results, leading > to String#plus, which returns the added lengths, which is 10 and > compatible with int.
yes, you're right, I've forgotten that you can change two methods at the same time. > >> Also, you should never use methods like >> |DefaultTypeTransformation.intUnbox| >> because you know that the return type is an int, you should >> back-propagate it and the return type of plus should be (Object;Object)I > in the original example that is true, yes. That may allow to skip at > intUnbox call... but only if I later select a plus method that returns > int or Integer. In a different thread I already asked for requirements > in that direction and that I get very differing results depending on > what signatures I use. No I have at lest the hint, that returning int or > Integer might be a good idea. if invokedynamic knows more, you can provide a path with less boxing so it's usually better. > >> Now, the generated code, because of getCallSiteArray(), >> your real code starts at line 168 and here you start >> to box the two ints to two Integers to be able to call >> NumberMath.subtract(Number,Number) which call >> IntegerMath.substractImpl that unbox them. >> The VM is not able to remove calls to box / unbox for j.l.Integer. > I see... unfortunate. > >> You should generate a must simpler path here. >> You should never call a class like g.r.typehandling.*Math because >> all of these methods takes Numbers as parameters. >> You should create one simple class, with methods like this: >> static int add(int left, int right) { >> return left + right; >> } >> because it doesn't force you to do the boxing. >> So you will do the boxing only if it's necessary, i.e. only >> when the parameter is Object. >> And to now which method you have to call, instead of >> relying on getMath() you should use guardWithTest and >> test only parameters that are Object. > Object is pretty often the case. Well if I count boxing and unboxing for > (a+b)+(c+d), then now I have to box a to d, unbox for the add, box the > result, no boxing for the outer plus call, but two unboxing and a boxing > for the result and... if the method returns int, a final unboxing. That > makes 7 boxing and 7 unboxing. > > If I use your add(II)I and backpropagate the return type, then I have > one boxing each for the inner pluses, two unboxing for the outer plus. > Totals to 2 boxing, 2 unboxing. Sounds better... even without > backpropagating the call. I will try that out. :) > > bye Jochen > cheers, Rémi _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev