abstract layouts
Ty Young
youngty1997 at gmail.com
Thu Aug 12 18:00:42 UTC 2021
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