Fwd: nullable-inlined-values on the heap

João Mendonça jf.mend at gmail.com
Sat Jul 2 00:47:10 UTC 2022


 Hello Brian,


Thank you very much for your replies.
I would like to start by saying that it's been a pleasure to listen and
read what you have been saying in these past few years on all kinds of
matters related to computer science. It's actually my appreciation of your
work, your clarity of thinking and your easy-to-understand explanations
that has led me here, trying to get some insight into the new and
fascinating things you are working on. Needless to say that, relative to
project Valhalla, practically all I know is what I have learned from you.
So I am well aware that if I am not agreeing or understanding something you
are saying I know that most likely you are right and I am wrong.
Having said this, I hope you continue to find this discussion worth having.
My feedback to your comments is below.


Except the model proposed actually had _more_ knobs than where we are now:
> just as many declaration-site knobs (no identity, tearable, zeroable), and
> more use-site knobs (atomic, nullable.)
>


Yes, I really haven't said much on this: The nullable-knob is "bang" and
the atomic-knob is basically "volatile". I gave it a different name because
reading through (§17.4.5.), it looks like "volatile" introduces
"Happens-before Order" which I understand does more than we need, which is:
just undo the effects of the tearable-knob. But maybe I am misinterpreting
this and the "volatile" we already have is just the atomic-knob I was
looking for.


Reading between the lines, what I think is going on here is: ".val is ugly,
> can we find a way to spell it !, so we can pretend there aren't really two
> things."
>


Maybe you are correctly reading between my mental lines, but I was actually
trying to make a deliberate effort to not care about syntax (which is a
valuable lesson I learned from you). That is why I have been calling
everything "such-and-such-knob".
But in fact, what you are saying here is precisely my point. We have two
complected things masquerading as one:

    1 - encoding-mode: reference - (nullable)
    2 - encoding-mode: inline - (non-nullable)

Encoding-mode and nullability are completely orthogonal concepts and I
think we have them complected simply due to convenience:

    1 - It's very easy/convenient to represent null with reference-encoding
    2 - It's cumbersome/inconvenient to represent null with inline-encoding

Also, when you say that unknowingly I am thinking: ".val is ugly, can we
find a way to spell it !" and "I want to say ?/!, not .ref/.val", what I
think I am thinking is:
"Runtime, this variable does/does-not need null in its value-set. Now you
decide what is best: ValType or RefType?"


The overwhelming lesson of Valhalla has been: every time we try to
> associate something with nullity (identity, reference-ness, flattening,
> atomicity, etc), it turns out to be a mistake.
>


Well, that is exactly my point: let's take the last step and decouple
nullity from everything, because right now, it still is associated with
reference-ness and flattening.
You have written about this conflict with nullability a few times now, and
that was actually a good part of the inspiration/reason that moved me to
write this.


Note that the RefType and ValType? in this breakdown are semantically
> identical!  The only difference is the assumed performance model --
> "reference vs inlined."
>


Yes, the point is to be able to modify the "performance model" without
affecting semantics. The user does not care about the encoding-mode, the
user only cares about:

    - identity
    - variable nullability
    - atomicity/tearing
    - zero-value hazards
    - performance/footprint

Ref-ness and flatness are just means to an end: delivering the highest
performance-model possible given the information provided by the user (via
the knobs). That is why I think .ref and .val should not be part of the
user-model but rather a runtime implementation detail.


But we *already* can do significant flattening on the .ref types (calling
> convention and locals.)
>


Actually, these very words were what led me to think: "Brian says we can
have nullable-inlined-values in non-shared-variables via some kind of
nullable-channel. Why not extend this trick to shared-variables as well?".


If we could achieve the kind of inlining you want for ValType? in the heap,
> we would just do it for RefType too, ...
>


Here, I am not sure I understand. I was under the impression that inlining
and RefType are opposite: A RefType is reference-encoded and a ValType is
inline-encoded.
>From what you are saying here, it looks like the definitions are simply:

    RefType: null | value-instances  (regardless of encoding-mode)
    ValType: value-instances         (regardless of encoding-mode)

Which makes sense as types are about value-sets and not about encodings. If
that is what you mean, then ValType? is exactly the same as RefType (as you
say) and my point translates to: let's inline RefTypes on the heap (§17.4.1.
shared-variables).
However, from what I have been reading in the mailing list, it appears that
the actual definitions are:

    RefType: null | value-instances + (atomicity, null-default,
higher-footprint, higher-latency)
    ValType: value-instances + (tearing, zero-default, lower-footprint,
lower-latency)

Which is also reasonable: types are about value-sets and also any other
associated semantic or runtime characteristics. But in that case I don't
understand your statement above, since under this definition, RefType and
ValType are tightly coupled with the encoding-mode:

    RefType: null | value-instances + (reference-encoding)
    ValType: value-instances + (inline-encoding)

Hence my proposed 3rd type:

    ValType?: null | value-instances + (inline-encoding)


I think there are at least two tails wagging this dog here -- the syntax
> tail (...) and the performance tail.
>


Here I must concede, I think I have been falling to the performance siren.
I have been focusing on the ValType? and I have named this thread
"nullable-inlined-values" when the most fundamental concept in my proposal
is "Decomplecting nullability from encoding-mode" or maybe "Trading
.val/.ref for nullable types".
Even if on nullable value-class shared-variables we cannot have
inline-encoding (as you say), we still get:

    - no more .val/.ref on the user-model
    - choice of .ref/.val is left for the runtime
    - the same performance-model as the currently proposed model
    - nullable types on the user-model


João Mendonça



On Fri, 1 Jul 2022 at 12:02, Brian Goetz <brian.goetz at oracle.com> wrote:

>
> If this is possible, maybe Valhalla's Java could have a user-model like
> this:
>
>
> You should probably start with what problem you are trying to solve.
>
>
> The poster offered the following clarifications:
>
> The problem it's trying to solve is to remove the .val and .ref
> operators/knobs/concepts from the user-model without any loss of
> performance or loss of control over nullability, zeroness or atomicity. In
> other words, the objective is to take Kevin's ref-by-default idea one step
> further.
>
>
> In theory, we could construct the union type int|Null, but this type
>> doesn't have a practical representation in memory, ...
>>
>
>
> Would it be possible to have a value-class give rise to these 3
> hidden/runtime-only companion-types on the heap:
>
>     RefType  - reference to a value-instance or no-reference (null)
>     ValType  - inlined [value-instance-fields]
>     ValType? - inlined [nullability-boolean + value-instance-fields]
>
> Then, the runtime could transparently choose between RefType|ValType for
> non-nullable variables or between RefType|ValType? for nullable variables,
> depending on hardware, bitSize, zeroness and atomicity constraints, as
> explained by the ternary expression in my previous email. Of course,
> since ValType? has a higher bitSize than ValType, nullable values will be
> less likely to be inlined. But still, the point is: could nullable values
> sometimes be inlined on the heap as opposed to never being inlined.
>
>
> In theory, we could construct the union type int|Null, but this (...)
>> drags in all sorts of mismatches because union types would then flow
>> throughout the system.
>>
>
>
> Is my 3-companion-types solution a real union type? Sure, I am suggesting
> two sort-of-unions:
>
>     RefType|ValType  - for non-nullable value-class variables
>     RefType|ValType? - for nullable value-class variables
>
> However, to the user, both types in each union represent the same exact
> value-set.
>
>
> My comments:
>
> Except the model proposed actually had _more_ knobs than where we are now:
> just as many declaration-site knobs (no identity, tearable, zeroable), and
> more use-site knobs (atomic, nullable.)
>
> Reading between the lines, what I think is going on here is: ".val is
> ugly, can we find a way to spell it !, so we can pretend there aren't
> really two things."
>
> And I totally get the desire to do this!  But I don't think these are the
> droids you are looking for.  The overwhelming lesson of Valhalla has been:
> every time we try to associate something with nullity (identity,
> reference-ness, flattening, atomicity, etc), it turns out to be a mistake.
>
>
> Would it be possible to have a value-class give rise to these 3
> hidden/runtime-only companion-types on the heap:
>
>     RefType  - reference to a value-instance or no-reference (null)
>     ValType  - inlined [value-instance-fields]
>     ValType? - inlined [nullability-boolean + value-instance-fields]
>
>
> I think there are at least two tails wagging this dog here -- the syntax
> tail (I want to say ?/!, not .ref/.val) and the performance tail.  Note
> that the RefType and ValType? in this breakdown are semantically
> identical!  The only difference is the assumed performance model --
> "reference vs inlined."  But we *already* can do significant flattening on
> the .ref types (calling convention and locals.)  If we could achieve the
> kind of inlining you want for ValType? in the heap, we would just do it for
> RefType too, and we wouldn't need a third thing.  So this breakdown is just
> making it needlessly more complicated for no benefit.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-comments/attachments/20220702/e5f82df7/attachment-0001.htm>


More information about the valhalla-spec-comments mailing list