Value Type on stack in the interpreter
I've some trouble to see how value types are laid on stack (conceptually, not necessary the real implementation). First, i may be wrong but it seems that vload do not reference the corresponding Q-type, so i wonder how the verifier knows that it can then access to component of the value type. Then, it seems that value type use one slot on stack, so the components (and the boxed reference if it exists) has to be stored somewhere but there is no corresponding max value type buffer size. Rémi
Re: Value Type on stack in the interpreter
On Mar 31, 2017, at 8:57 AM, Remi Forax wrote: > > I've some trouble to see how value types are laid on stack (conceptually, not > necessary the real implementation). > > First, i may be wrong but it seems that vload do not reference the > corresponding Q-type, so i wonder how the verifier knows that it can then > access to component of the value type. > Then, it seems that value type use one slot on stack, so the components (and > the boxed reference if it exists) has to be stored somewhere but there is no > corresponding max value type buffer size. In the interpreter value types all share a common _carrier type_ which includes metadata about the size and type of the value being stored, plus a pointer to the actual storage. The actual storage may be on the heap, or maybe not. We are prototyping with thread-local arenas for the non-heap case. There are also ways to store value payloads in the stack frame, but in that case there is a special handshake when you want to return a value from a method call. From the verifier's point of view, there isn't much difference between the various Q-types. We will probably track classes of Q-types, mainly to simplify vgetfield operations. — John
Re: Value Type on stack in the interpreter
- Mail original - > De: "John Rose" > À: "Rémi Forax" > Cc: valhalla-spec-experts@openjdk.java.net > Envoyé: Samedi 1 Avril 2017 01:06:07 > Objet: Re: Value Type on stack in the interpreter > On Mar 31, 2017, at 8:57 AM, Remi Forax wrote: >> >> I've some trouble to see how value types are laid on stack (conceptually, not >> necessary the real implementation). >> >> First, i may be wrong but it seems that vload do not reference the >> corresponding >> Q-type, so i wonder how the verifier knows that it can then access to >> component >> of the value type. >> Then, it seems that value type use one slot on stack, so the components (and >> the >> boxed reference if it exists) has to be stored somewhere but there is no >> corresponding max value type buffer size. > > In the interpreter value types all share a common _carrier type_ which > includes > metadata about the size and type of the value being stored, plus a pointer to > the actual storage. The actual storage may be on the heap, or maybe not. > We are prototyping with thread-local arenas for the non-heap case. > There are also ways to store value payloads in the stack frame, but > in that case there is a special handshake when you want to return a > value from a method call. Ok, why the type of the value is stored in the _carrier_type_ and not in the vload/vstore instruction. > > From the verifier's point of view, there isn't much difference between > the various Q-types. We will probably track classes of Q-types, mainly > to simplify vgetfield operations. pre-compute the offset of a component ? > > — John Rémi
Re: Value Type on stack in the interpreter
On Mar 31, 2017, at 4:30 PM, fo...@univ-mlv.fr wrote: > > - Mail original - >> De: "John Rose" >> À: "Rémi Forax" >> Cc: valhalla-spec-experts@openjdk.java.net >> Envoyé: Samedi 1 Avril 2017 01:06:07 >> Objet: Re: Value Type on stack in the interpreter > >> On Mar 31, 2017, at 8:57 AM, Remi Forax wrote: >>> >>> I've some trouble to see how value types are laid on stack (conceptually, >>> not >>> necessary the real implementation). >>> >>> First, i may be wrong but it seems that vload do not reference the >>> corresponding >>> Q-type, so i wonder how the verifier knows that it can then access to >>> component >>> of the value type. >>> Then, it seems that value type use one slot on stack, so the components >>> (and the >>> boxed reference if it exists) has to be stored somewhere but there is no >>> corresponding max value type buffer size. >> >> In the interpreter value types all share a common _carrier type_ which >> includes >> metadata about the size and type of the value being stored, plus a pointer to >> the actual storage. The actual storage may be on the heap, or maybe not. >> We are prototyping with thread-local arenas for the non-heap case. >> There are also ways to store value payloads in the stack frame, but >> in that case there is a special handshake when you want to return a >> value from a method call. > > Ok, > why the type of the value is stored in the _carrier_type_ and not in the > vload/vstore instruction. There are two choices: 1. store the type metadata in the carrier (on stack and in local), or 2. reaffirm the type metadata at every use site (not just vload/vstore). #1 allows simpler bytecodes which put less load on the verifier. A significant subset of #2 is needed, anyway, for telling the GC where to find object references. So #2 wins. > >> >> From the verifier's point of view, there isn't much difference between >> the various Q-types. We will probably track classes of Q-types, mainly >> to simplify vgetfield operations. > > pre-compute the offset of a component ? Yes, as with objects. The techniques are basically the same. Q-types behave like on-stack objects. (They are also copy-able hence identity-free, and they are also non-nullable.) — John
Re: Value Type on stack in the interpreter
On Mar 31, 2017, at 5:00 PM, John Rose wrote: > > There are two choices: 1. store the type metadata in the carrier (on stack > and in local), > or 2. reaffirm the type metadata at every use site (not just vload/vstore). > #1 allows > simpler bytecodes which put less load on the verifier. A significant subset > of #2 > is needed, anyway, for telling the GC where to find object references. So #2 > wins. P.S. And that's before we get into layout-polymorphic generics and type variables that include Q-values. Those also require the robust carrier type of #2. Option #1 was always a mirage.