stored properties in extensions (was: associated objects)

I was thinking for reference types we would probably want to use the extra space in the refcount field (as discussed earlier in the thread). For value types, we might want to have a single data structure (probably COW) holding all associated values for the value types on the stack frame. That way, we don’t have to double the size of an Int if someone adds an associated value in one or two cases. We only add a pointer size to the entire stack frame in the case where no value types have associated values.

Thoughts?

Thanks,
Jon

···

Karl, interesting point... perhaps a similar scheme could work for value
types (using the COW refcount)?

On Thu, 13 Oct 2016 at 16:02 Karl Wagner <razielim at gmail.com <https://lists.swift.org/mailman/listinfo/swift-evolution&gt;&gt; wrote:

> That's great! I suppose the idea of allocating a bit of extra storage for
> similar data in value types is some sort of heresy?
>
> Would there be a conceptual reason for that; which explains why it's okay
> for reference-types but not for values? Personally I feel like it's a kind
> of C legacy, due to performance and layout expectations that C sets about
> value-types ¯\_(ツ)_/¯
>
> Karl
>
>
> Sent from my iPad
>
> On 12 Oct 2016, at 07:54, Greg Parker <gparker at apple.com <https://lists.swift.org/mailman/listinfo/swift-evolution&gt;&gt; wrote:
>
>
> On Oct 11, 2016, at 3:02 PM, Jay Abbott via swift-evolution < > > swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution&gt;&gt; wrote:
>
> Implementation idea No. 4:
>
>
> The basic concept is that the dynamic linker would fixup the offsets as
> well as relocating the addersses, allowing the size of objects (and maybe
> structs?) to change at link-time. The process might be something like this:
>
> * References to members defined in extensions would compile to have an
> offset symbol instead of a value - so they can be fixed up later
> * The linker would scan all the shared objects that are referenced (and
> thus might get linked)
> * Build up a list of Stored Properties In ExtensionS (SPIES, muhahaha) for
> each class.
> * Append the extra fields (increase the size the class), decide where each
> member goes in the extended layout and fixup the offsets
> * Carry on with normal relocation
>
> There are quite a few assumptions in the above, and probably quite a few
> misunderstandings about how things work on my part too (I'm not an expert
> at this), however I think it should work in principle. Some questions about
> my assumptions: Can linker know in advance all the potential modules that
> could be linked, or is this done more lazily and it only knows about what
> it's linking right now? Is it ok for the size to change - I don't know if
> it's a static sizeof() or if it could be (or already is) stored in the isa?
>
>
> This sort of scheme isn't dynamic enough. The worst-case is a extension in
> a library that gets dlopen()ed at runtime on a class that is already
> loaded. The build-time linker can't know anything about it. The loader and
> the runtime will see it, but at that point the class may already be in use
> and may already have instances allocated. If you want to handle the
> dlopen() case then you need some way to add storage to arbitrary objects
> that have already been allocated.
>
>
> Ole Begemann wrote:
>
>
> For what it's worth, Greg Parker (Cc'ed) started a discussion back in
> March that I think is relevant here:
> https://lists.swift.org/pipermail/swift-dev/Week-
> of-Mon-20160314/001424.html
>
> Here's the relevant part:
>
> "I am considering a new representation for Swift refcounts and other
> per-object data. This is an outline of the scheme. Comments and suggestions
> welcome.
>
> Today, each object stores 64-bits of refcounts and flags after the isa
> field.
>
> In this new system, each object would store a pointer-size field after the
> isa field. This field would have two cases: it could store refcounts and
> flags, or it could store a pointer to a side allocation that would store
> refcounts and flags and additional per-object data.
>
> Advantages:
> …
> * Allows inexpensive per-object storage for future features like
> associated references or class extensions with instance variables.
> …"
>
> I don't know the current status of this idea (implemented? planned?
> abandoned?). Also, it's worth noting that this would only apply to classes,
> not value types.
>
>
> I'm working on this right now:
> https://github.com/gparker42/swift/tree/new-refcount-representation
>
> If it goes well it will provide the runtime implementation space needed
> for associated objects or stored properties in extensions. Such storage
> would be less efficient than "real" stored properties. Any object with that
> storage attached would also suffer additional performance penalties to
> refcounting and deallocation. On the plus side there is no memory penalty
> to objects that don't have additional storage, and there is no contention
> over a big global association table like there is in Objective-C's
> associated object implementation.
>
> Note that the runtime implementation is not the only problem. The
> optimizer folks hate the fact that stored properties in extensions defeat
> the compiler's visibility into the deinit behavior of all types, even if
> most types are unaffected at runtime.
>
>
> --
> Greg Parker gparker at apple.com <https://lists.swift.org/mailman/listinfo/swift-evolution&gt; Runtime Wrangler
>
>
>