2012/4/22 Rémi Forax <fo...@univ-mlv.fr>: >> So as you can see, 30 and 12 are not recognized as constants. > > You're right, 30 and 12 are not recognized as int constant > but they are recognized as java/lang/Integer constant. > > 0x00007f785ca29706: mov $0x7d66619d8,%r10 ; {oop(a 'java/ang/nteger' = > 30)} > > so escape analysis works but Hotspot doesn't trust > final field thus doesn't consider the value in the Integer > as a constant.
I see why HotSpot can't in general trust the 'final' keyword, but it sure would be nice if it can at least for these boxed types. After all, if Integer.value is modified via reflection, all kinds of weird things start to happen... >> After a few more experiments, I realize the root cause of this isn't >> so much as JSR-292 but more in HotSpot. For example, the following >> method produces the following assembly code, and as you can see it's >> failing to optimize body() into just "return false". > > In fact, Hotspot doesn't fail. > But Hotspot also obfuscates the code :( > >> So my question is: >> >> - Am I missing something? > > yes :) > in that case, the body of 'body' is > (there is a ret at 0x00007fadf244130c) > > 0x00007fadf24412e6: mov $0x7d6602fe0,%r10 ; {oop(a 'java/lang/Class' = > 'java/lang/Boolean')} > 0x00007fadf24412f0: mov 0x74(%r10),%r8d ;*getstatic FALSE This is doing "Boolean %r8 = Boolean.FALSE" > java.lang.Boolean::valueOf@10 (line 149) > ; - > BoxedBooleanInlineTest::bool1@1 (line 29) > ; - > BoxedBooleanInlineTest::body@1 (line 21) > 0x00007fadf24412f4: movzbl 0xc(%r12,%r8,8),%r11d This is doing "%r11 = %r8.value" with proper sign bit expansion > 0x00007fadf24412fa: test %r11d,%r11d and this is testing if %r11 is 0. > 0x00007fadf24412fd: jne 0x00007fadf244130d ;*iconst_0 > ; - > BoxedBooleanInlineTest::body@24 (line 21) > 0x00007fadf24412ff: xor %eax,%eax ;*ireturn and yes, this is "return 0" > The code is fully optimized xor %eax, %eax put 0 in eax, > which is by convention the register containing the return value > and the rest of the code is not used. > The question here is why Hostspot generates the unnecessary codes > above the xor instruction. The code tests that zero is equals to zero > before returning zero :) I don't see that as a question. As I said and as you observed earlier, this code is *not* fully optimized, in that it doesn't treat "Boolean.FALSE.value" as a constant. And under that assumption, every instruction in the above code does make sense. >> - How do other language implementers cope with this? > > You are the first as far as I know to use only a tree of method handles > to implement expressions. The rest of us generates bytecodes > and have a compiler that does constant propagation. OK, that's good to know, but I'm not seeing how that changes the picture. The issue is that, as things stand now, the language runtime would have to do the type inference to use primitive types instead of Object, or else it won't benefit from constant propagation (which triggers other optimizations like dead code elimination and further escape analysis.) Say I compile "a.foo() && a.bar()" in JEXL to a byte code (or "a.foo && a.bar" in JRuby if that helps people understand the example better.) Unless I can somehow prove that "a.foo()" returns a boolean, I'd have to treat it like they return Object. And so even if at the runtime HotSpot discovers that "a" is mostly bound to a specific type that implements foo() as "return true", it ends up in the assembly code like my example (with the guard if statement on top to check if the type of 'a' is of this common type), not the equivalent of "return false" --- suboptimal result. Yet as I see it, such type inference is hard/impossible for most dynamic languages. I certainly don't see how JRuby can do that. And I thought the whole point of this new addition in Java7 was to let HotSpot do these optimizations, as opposed to have each language runtime do it. So again, I don't see how shifting from method handle tree to byte code generation would somehow make this non-issue. But I think I got the answer to half of my questions anyway --- that I wasn't failing to have HotSpot optimize to its fullest potential, and instead it's the design choice / current shortcoming in HotSpot that it doesn't consider "Boolean.FALSE.value" as "false". That leaves me just with the other question, that how other implementors are coping with this. The observation from Mark was interesting --- maybe it actually doesn't cost as much as it looks in the assembly, with branch prediction and Boolean.FALSE on cache, etc. OTOH, I still think the constant propagation can trigger more optimizations and those add up to something non-trivial... -- Kohsuke Kawaguchi _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev