Primitive Queue<any T> considerations
vitalyd at gmail.com
Wed Nov 18 23:47:06 UTC 2015
By "touching the heap" I was referring to stack allocated value types
getting boxed and roundtripped via the heap, not them being embedded in a
heap object. I have a ton of use cases where I'd like to do data
encapsulation on-stack and have guarantees that storage is on stack; if JIT
scalarizes across registers, I view that as an optimization. Most
important is no heap allocation occurs. If I give the JVM a 1000 byte
struct, I expect it to grow the stack by that amount and copy it; if that
overflows, send me a StackOverflowError, no problem. Mind you, I (and I'm
sure others) have no plans of 1000 byte structs, but I can easily see some,
not many, that are in the 64-128 byte range. I'd like this to work just
like if I had written a method accepting 8-16 individual long arguments.
The overarching theme here is I'd like to use the stack a lot more, for
ephemeral/temp storage, and have that guaranteed rather than hope and pray
escape analysis does its thing. I don't want TLAB or some other thread
local heap segment, I want the stack to be my TLAB :).
sent from my phone
On Nov 18, 2015 6:25 PM, "John Rose" <john.r.rose at oracle.com> wrote:
> On Nov 18, 2015, at 12:38 PM, Vitaly Davidovich <vitalyd at gmail.com> wrote:
> A large point of value types
> is they do not touch the heap, and thus do not contribute to any subsequent
> GC pauses. If I had a large struct, I may be just fine having a slower
> copy operation percolating through the stack. This is like escape
> analysis, nobody that's avoiding GC is actually relying on it because of
> this "VM's choice" aspect. I urge you to reconsider this automatic boxing
> aspect. Nobody is going to complain that the JVM is not automatically
> boxing their large struct, but someone will complain if there's heap
> allocation behind the scenes.
> This is an interesting question, especially since early prototyping
> of value types may involve a surprising amount of boxing,
> particularly for "hard cases" like the large struct you mention.
> The above is a good argument to remember, though.
> I suppose you mean copies between locals: Those
> should not copy through the heap, in common cases.
> A non-small value type will probably need buffering,
> but the buffer can be allocated using stack rules,
> refcount rules, or the like, so it can be deallocated
> in a timely manner without GC interaction.
> (BTW, it is possible we will decide that de-opt
> transitions will use heap copies, at least at first.)
> It seems there are three interesting value type sizes.
> Small ones fit in a register or two, and/or can be
> atomically loaded and stored by hardware.
> Large ones span multiple cache lines, and
> have only limited benefit compared to objects.
> In the middle, the medium ones require several
> instructions to store (and extra work for atomicity)
> but still occupy the natural unit of memory, which
> is a cache line (or two, relying on prefetch).
> they do not touch the heap
> Value types can touch the heap in various use cases,
> in the same way that ints can be stored in the heap,
> or (new to value types) in that they can contain refs.
> It is true that using value types will reduce GC load in
> many cases (besides local-to-local copies), but this
> is mainly because of their flatness, which reduces
> memory pressure and decreases frequency of
> dependent loads.
> — John
More information about the valhalla-dev