[foreign-memaccess] on layout equality
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Jul 23 23:13:37 UTC 2019
Thanks John,
what you say makes sense. This is actually the model we have followed in
the foreign branch, where layout comparison looks at annotations, but
then there's a stripAnnotations() method.
My initial goal was to explore this decision and see whether we could
come up with something which made annotations less important - but as
both you and Jorn pointed out separately, it will be common for people
to stick these things into maps/sets and then rely on equality to do the
right thing. And, given that some of these annotations end up having
quite important side-effects ABI-wise, lumping layouts with different
ABI semantics together is not such a great idea after all.
Still, I think it was good to have this discussion, as this was an
aspect that wasn't given much attention when designing the Layout API in
the foreign branch - it seems like we did the right choices there, but
it's good to have them validated explicitly.
Cheers
Maurizio
On 23/07/2019 22:47, John Rose wrote:
> The four alternatives boil down to what I call “lumping” equals, “splitting” equals, both, or neither.
>
> Equality predicates split their inputs into equivalence classes. A splitting one creates many small
> classes, while a lumping one does the opposite. The ideal splitting predicate is a logical
> “substitutability test”, which has the unique property that any other predicate (in some defined
> universe of predicates carefully protected from extension by marauders like Godel or Cohen
> or Robinson) is unable to make a distinction between two objects in the same equivalence
> class. Substituting one term for the other will, therefore, preserve truth value of any proposition
> whatever. It’s an ideal, but surprisingly implementable, once you have clarity on your universe
> of predicates. (VBC’s in Java refuse to “look at” synchronization conditions, and so will inline
> types.) In any case, given a splitting predicate (ideal or not) you can make it more lumpy
> by preprocessing the inputs to ”throw away” unwanted bits, so they look equal to the splitting
> predicate in their processed form even if they were not, to begin with.
>
> Practically speaking, it’s safer in many cases to build in lots of splitting (except all the way
> to object identity) into `C.equals` for some `C`, and then provide various ad hoc projection
> methods to “forget” or “normalize” or “strip” values of `C` for various use cases. The projected
> values serve as “leaders” of lumpy equivalence classes, as keys for hash maps, etc.
>
> Going the other way (lumpy to splitty) is harder, because you have to extract the ignored
> bits from the `C` value (a buggy business), put them into a temporary structure (costly),
> and then adjoin a comparison of the temporary structure to the lumpy “native” comparison
> of `C`.
>
> Also, a lumpy comparison on `C` will occasionally surprise users who use the `C` values
> as keys to caches, if the cached values depend on bits discarded from `C.equals`. This
> can cause nasty bugs.
>
> So I suggest #2 as the most robust option. If users don’t like the splitting they can normalize
> their keys by throwing away the bits *they* think are unimportant.
>
> — John
>
> On Jul 23, 2019, at 6:38 AM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
>> Hi,
>> there is one aspect of the layout API that we have not explored fully: how should layout behave w.r.t. equality? There are the following options:
>>
>> 1) equality should only test 'core' properties of the layout (e.g. size, alignment, ...)
>> 2) equality should also include optional, side-channel info such as layout names (or, in the foreign-abi branch, layout annotations)
>> 3) we should have both flavors of equality
>> 4) do not support equality at all
>>
>> Between (1) and (2), I think I lean towards (1). Yes, we can attach a name to a layout, but doing so does NOT change the layout properties - the layout still has same size, alignment, etc. On the other hand, (3) seems like overkill and (4) seems overly punitive. I say "seem" because I really don't know here how people will be using layouts, and it is very possible that we are jumping to the conclusion that layouts must somehow be comparable with equals() because our implementation internals is happy this way. As Brian pointed out once, it is very likely that layouts will be constructed, stashed in a static field and never looked at again. In which case an answer like (4) is not totally out of the question.
>>
>> What do people think on this?
>>
>> Cheers
>> Maurizio
>>
More information about the panama-dev
mailing list