Escape Analysis and Stack Allocation (original) (raw)
Jeremy Manson jeremymanson at google.com
Mon Jan 27 23:44:50 PST 2014
- Previous message: Escape Analysis and Stack Allocation
- Next message: Escape Analysis and Stack Allocation
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
That was basically what mine did, too. I put on a pointy hat and became more of a manager than a programmer, but I never stopped wondering what would happen if I had an opportunity to wire the two things together.
There are obvious optimizations to make, too. For example, the MLAB doesn't have to go in the YG - it could go in a generation devoted to them. They can be stolen by a second thread when the first thread blocks (TLABs could do this, too - always wondered why they didn't). You would probably want to resize MLABs like you resize TLABs. It's a career path getting it right.
If you have something that can go into HS24 pretty easily, I can probably slap it in and try it out on some programs that are substantially more interesting than jbb2005. Might be hard to revive after four years, though.
Jeremy
On Mon, Jan 27, 2014 at 10:08 PM, Vladimir Kozlov < vladimir.kozlov at oracle.com> wrote:
I did the same experiment 4 years ago, back in jdk6 era. Called it MLAB, method local allocation buffer, works like thread local stack for non-escaping objects but was allocated in java heap as special TLAB. Got it worked but did not see benefits in jbb2005. GC requires no holes in heap, as result I had to give the buffer back to GC when young gen collection was needed. After GC a thread get new MLAB and starts allocation from scratch which nullified performance benefits.
I can try to find those changes if someone interested. Regards, Vladimir
On 1/27/14 9:21 PM, Jeremy Manson wrote: I tried implementing direct stack allocation in Hotspot a couple of years ago. It was a pain to try to allocate anything outside the heap - there are a lot of checks to make sure that your objects live on the heap.
I ended up creating TLAB-like regions in the heap that could hold objects allocated in a stack-like way. It was a lot easier that way, and seemed to give the kinds of performance benefits you would expect. I never got around to trying to wire it up to Hotspot's escape analysis, but it was a fairly obvious next step. Jeremy
On Sun, Jan 26, 2014 at 12:26 PM, Aaron Grunthal <_ _aaron.grunthal at infinite-source.de> wrote: There also is an issue with merge points [1] which prevents objects in loops with an accumulator (e.g. reduce operations on streams) to stack-allocate the intermediate values. [1] https://bugs.openjdk.java.net/browse/JDK-6853701 - Aaron
On 26.01.2014 07:04, Benedict Elliott Smith wrote: Hi, I was digging into some (to me) unexpected behaviour of escape analysis, namely that some references that clearly weren't escaping, and easily determined to be so, were not being stack allocated. So, after some digging through the hotspot code, I discovered some things that were probably obvious to everyone on this list, but also some things I'm still a little perplexed about. I was hoping somebody could enlighten me about the latter. 1) I cannot see a reason why stores to a primitive array, for instance, should cause the argument to escape in bcEscapeAnalyser.cpp iterateoneblock(); most interestingly, a store to an object array does not result in this, which seems incongruous; 2) An object array store does however result in setglobalescape() for the value being stored, which makes sense, except that this should only be setmethodescape(), as per the paper, in the case where the target array is one of the method arguments. This seems to be missing, here and for putfield. Some other weird ones are arraylength, getfield, ifnonnull, etc. The fact that these all result in setmethodescape(), and that putfieldand aastore don't optimise setglobalescape() to *setmethodescape()*where possible, seem to point to the conclusion that *isargstack / setmethodescape()* actually encode only !isscalarreplaceable. Is this the case? If so, why the confusing name?*
Which leads to a much trickier but more interesting question, which is: what are the barriers to performing actual stack allocation of full objects, instead of scalar replacement? It is something I would be keen to investigate, but given my lack of familiarity with the codebase, it would be immensely helpful to hear what the major difficulties / showstoppers might be before trying to attack it. Thanks in advance, Benedict *I do note that in escape.cpp ArgEscape is defined and is explicitly overloaded to include some of the characteristics of isscalarreplaceable. However the isargstack() method is commented with "The given argument escapes the callee, but does not become globally reachable." which seems to correspond to ArgEscape in the paper, but only invoke() seems to follow the spec, when invoking a method that cannot be analysed, and this would also be true for !isscalarreplaceable.
- Previous message: Escape Analysis and Stack Allocation
- Next message: Escape Analysis and Stack Allocation
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]