On Feb 24, 2009, at 10:22 AM, Charles Oliver Nutter wrote: > - General reduction in bytecode size. Simply having less bytecode > seems > to have a large effect on how well Hotspot is able to consume the > code. > There are also size limitations on inlining code, so less bytecode > often > means more inlining. > - Reduction in numbers/complexity of branches. This also plays into > total bytecode size, but I've seen improvements from simply flipping > loops around or calculating jump conditions in aggregate before > making a > single jump. > - Outline as much code as humanly possible (as opposed to inlining). > JRuby's compiler originally just emitted all logic straight into the > method body. This turned out pretty badly; it was very slow, and there > was a tremendous amount of duplication. By pulling as much as possible > into static utility methods, bytecode size was drastically reduced and > performance went up substantially.
Thanks, Charlie. Those are great rules of thumb. They probably belong somewhere on the internals wiki, despite the warnings that it is not a tuning document. Branch-to-branch doesn't matter much for HotSpot, since it uses SSA and sea-of-nodes IR. Recently, we have added a pre-pass to make sure the IR is generated in RPO, regardless of concrete bytecode structure. This makes the initial JIT steps more strongly normalizing, hence more reliably optimizing. I imagine the other JVMs do similar "due diligence" on their JIT inputs. For language runtimes the JVMs should supply more hooks for affecting JIT-level inlining, maybe something as simple (in HotSpot's case) as @sun.misc.Inline. I'm not aware of a credible effort to standardize on it, though. Branch-free idioms (as long as they are simple and do not greatly expand bytecode size) are helpful. The Hotspot JIT is pretty good at turning simple control flow into branch-free code when possible, but in very simple cases it is more reliable to write it in Java code. The main problem is that bytecodes cannot express conditional move directly; the best you can do is control from from x = p ? x1 : x2. The important thing to encourage conditional moves is that the predicate p and one or both of the conditional values x1, x2 should free of side effects and exceptions, such as constants or variable references. Always use -XX:+PrintAssembly to see what you are doing. BTW, +PrintCompilation is a very *old* flag; +LogCompilation is slightly less old. The newest thing here, probably is that +PrintAssembly is now a diagnostic switch, which means it works for product builds (after being unlocked). You need a disassembler plugin, and I'm pleased to announce that this is now second-sourced (x86/32 only at present) at http://kenai.com/projects/base-hsdis/ . You may still need to do a build, but hopefully the extra option will make it easier for some. Best, -- John --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en -~----------~----~----~----~------~----~------~--~---
