abstract layouts
Ty Young
youngty1997 at gmail.com
Thu Aug 12 18:49:14 UTC 2021
My understanding is that if:
-XX:+UnlockExperimentalVMOptions
-XX:+TrustFinalNonStaticFields
are set then non-static final fields are optimized. Is that not true?
Anyway, I don't want to hear anything about what I'm doing being
"problematic" when the whole reason I'm doing what I'm doing is because
of issues with FMA/FFI API. If you don't like it then open up layouts,
otherwise I really don't want to hear it. It was well known that
attributes were going to be used(and was even encouraged) for this
purpose so I have no clue why all of a sudden it's a bad idea in your
mind. I knew it was less optimal idea well over a year ago, but it's not
like I have the power to change it.
On 8/12/21 1:27 PM, Maurizio Cimadamore wrote:
> I think what you are trying to do is problematic.
>
> You have NativeInteger, and NativeInteger has a static layout. You
> want to attach other static information (method handles). The
> information has to be _static_ if you want to have any chance of the
> JVM to optimize all that.
>
> But, with attributes, you are storing the MHs in a map - so, not
> static. Even if you could declare your own layout class, storing the
> method handles in final fields of the custom layout won't help (if the
> final fields aren't trusted by the JVM, which they are not, except for
> special provisions for some JDK packages).
>
> In other words, I don't see a path (besides spinning a new
> NativePointer64 instance which is exclusively dedicated to
> NativeInteger) by which you can get performance when accessing the
> NativeInteger from the NativePointer64.
>
> But, if you don't care much about inlining/performance, then maybe you
> can just use a ClassValue and store all the MethodHandles related to
> NativeInteger in there? That is going to provide similar (if not
> better) performance than those with layout attributes.
>
> I guess what I'm trying to say is that, unless I misunderstood your
> example, it seems another case of "layout attributes are attractive
> nuisance" - e.g. once they are there, one is tempted to just inject
> stuff into layouts, but you already have custom classes wrapping
> layouts, so why don't you associate the (static) metadata with the
> classes, rather than the layouts?
>
> Maurizio
>
> On 12/08/2021 19:00, Ty Young wrote:
>> Because it's needed for a NativePointer64 type:
>>
>>
>> NativePointer64<NativeInteger> intPointer = new
>> NativePointer64<>(NativeInteger.LAYOUT);
>>
>>
>> NativeInteger has 3 MethodHandles embedded into it, one which accepts
>> nothing(safe), one which accepts a MemorySegment(unsafe), and one
>> which accepts a MemoryAddress(unsafe, what is used by
>> NativePointer64). NativePointer then takes the given layout, embeds
>> it inside of itself, then reads it later when getting the
>> dereferenced value. Doing this generates garbage because of Optional
>> since the NativePointer64.LAYOUT needs to have NativeInteger embedded
>> inside of it, which then needs to be resolved according to a type
>> attribute, e.g. enum, pointer, number. It's wasteful(in terms of
>> memory) and slow(have to go through a tree of static methods to
>> resolve). Layouts being opened up would help.
>>
>>
>>
>> On 8/12/21 8:39 AM, Maurizio Cimadamore wrote:
>>> May I suggest, for the benefit of the conversation, that instead of
>>> focusing on the _hows_ we focus instead on the _whys_ ?
>>>
>>> E.g. "I'd like to decorate a layout with information X and Y,
>>> because I use these information in order to do Z"
>>>
>>> In other words, by having a full picture of what you are trying to
>>> do we might understand better what the requirements really are.
>>>
>>> Thanks
>>> Maurizio
>>>
>>> On 12/08/2021 14:12, Maurizio Cimadamore wrote:
>>>>
>>>> On 12/08/2021 12:24, Ty Young wrote:
>>>>> I'd very much like it if layouts were opened up and non-sealed. It
>>>>> would allow for less wasteful(no Optional) and faster code(no
>>>>> HashMap, things can be final).
>>>> I agree that would work better.
>>>>
>>>>> It also would be nice if GroupLayout was removed and replaced with
>>>>> StructLayout and UnionLayout, or used as a shared/common
>>>>> interface/class for them.
>>>> That is largely orthogonal and irrelevant in the discussion we're
>>>> having here.
>>>>>
>>>>>
>>>>> I feel like the with* issues could be fixed with generics, e.g.:
>>>>>
>>>>>
>>>>> public interface MemoryLayout<L extends MemoryLayout<?>> {
>>>>>
>>>>> public L withName(String name);
>>>>>
>>>>> }
>>>>
>>>> I don't think this solves much - as you will have, likely:
>>>>
>>>> ValueLayout extends MemoryLayout<ValueLayout>
>>>>
>>>> At which point you're back to square one - if you define `TyLayout
>>>> extends ValueLayout`, there's nothing forcing you to override
>>>> withName.
>>>>
>>>> I did experiments adding generic types to all layouts two years ago
>>>> and honestly, it doesn't work very well. About 99% of the times,
>>>> the most helpful thing the client has to say about a layout is
>>>> MemoryLayout<?>, which seems like forcing 99% of the users to use
>>>> generics because 1% of use cases might need them. But that's beside
>>>> the point - generics do not solve the problem I was talking about.
>>>> Also, in my experience, having f-bounded type variables in
>>>> hierarchies works very well when you have one top class and a
>>>> single level of leaves (which are all peers). It works much less
>>>> when you have to start defining sub-hierarchies in the leaves -
>>>> because either the intermediate nodes are conscious about the type
>>>> variables and leave them open (leading to very verbose and
>>>> borderline uncomprehensible generic declarations), or they fix the
>>>> type variables, in which case the leaves will not take advantage of
>>>> the f-bound, and you'll be back in no-generic-land.
>>>>
>>>>
>>>>>
>>>>> All of the basic layout types should be interfaces, not classes
>>>>> IMO. Basic implementations could be put in a non-exported package.
>>>>> Users can get a basic implementation from MemoryLayout static
>>>>> methods, as they do now.
>>>> Again, this seems a bit of a shallow comment. We can turn layouts
>>>> from interface to classes in 2 minutes, by doing a targeted
>>>> refactoring. But again, whether classes or interfaces, the problem
>>>> I pointed out is still there and is the one we'd need to solve to
>>>> be able to let clients to subclass layouts freely.
>>>>>
>>>>>
>>>>> I don't think what I'm proposing could be done with static
>>>>> decorator methods. The information being added as attributes
>>>>> include MethodHandles for the class's constructor, e.g. a
>>>>> constructor MethodHandle for a NativeInteger class, something that
>>>>> specific can only be done at the class level I think.
>>>>
>>>> Well, the original proposal was to add a bunch of methods:
>>>>
>>>> * MemoryLayout::isAbstract
>>>> * MemroyLayout::asAbstract
>>>> * MemoryLayout::unfilledAttributes
>>>>
>>>> If we have layout attributes (like we do in today's API), there is
>>>> no need for these methods to _be_ in MemoryLayout. They can be
>>>> static methods taking a layout, defined wherever you want. Just use
>>>> a special name to encode the attribute names - e.g. "abstract/foo"
>>>> - then:
>>>>
>>>> * isAbstract --> does the layout have any attribute whose name
>>>> starts with "abstract/" which are set to null?
>>>> * asAbstract --> encode the attribute names to use the "abstract/"
>>>> prefix
>>>> * unfilledAttributes -> get all the attributes whose name start
>>>> with "abstract/" and return those that have no value set
>>>>
>>>> Maurizio
>>>>
>>>>
>>>>
>>>>
More information about the panama-dev
mailing list