libc++ internals visibility rational

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

libc++ internals visibility rational

Richard Pennington via cfe-dev
Hi,

I’m wondering about libc++ visibility for the internals of the library. For example why do we define:

_LIBCPP_INLINE_VISIBILITY
    void __construct_at_end(size_type __n, const_reference __x);
   
with inline/hidden visibility, but not this one:

template <class _ForwardIterator>
typename enable_if  <__is_forward_iterator<_ForwardIterator>::value, void>::type
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);


Thanks,


Mehdi

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: libc++ internals visibility rational

Richard Pennington via cfe-dev
Similarly with the public free template functions:


template <class _L0, class _L1>
void
lock(_L0& __l0, _L1& __l1)

and

template <class _L0, class _L1, class _L2, class ..._L3>
inline _LIBCPP_INLINE_VISIBILITY
void
lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& …__l3)



Mehdi



> On Mar 31, 2017, at 10:46 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
>
> Hi,
>
> I’m wondering about libc++ visibility for the internals of the library. For example why do we define:
>
> _LIBCPP_INLINE_VISIBILITY
>    void __construct_at_end(size_type __n, const_reference __x);
>
> with inline/hidden visibility, but not this one:
>
> template <class _ForwardIterator>
> typename enable_if  <__is_forward_iterator<_ForwardIterator>::value, void>::type
> __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
>
>
> Thanks,
>
> —
> Mehdi
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: libc++ internals visibility rational

Richard Pennington via cfe-dev
Honestly I've been wondering about the same things.

Libc++ needs to re-evaluate it's entire approach to symbol visibility especially w.r.t ABI management.
I think a lot of the existing behavior is purely historical, and newer parts of the library just try to mimic that
regardless of QoI. In particular I'm sceptical that libc++'s use of __always_inline__ helps prevent "ABI problems".

I would love to start a discussion on this, especially if it leads to concrete example
that can be turned into test cases

/Eric


On Fri, Mar 31, 2017 at 11:57 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
Similarly with the public free template functions:


template <class _L0, class _L1>
void
lock(_L0& __l0, _L1& __l1)

and

template <class _L0, class _L1, class _L2, class ..._L3>
inline _LIBCPP_INLINE_VISIBILITY
void
lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& …__l3)



Mehdi



> On Mar 31, 2017, at 10:46 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
>
> Hi,
>
> I’m wondering about libc++ visibility for the internals of the library. For example why do we define:
>
> _LIBCPP_INLINE_VISIBILITY
>    void __construct_at_end(size_type __n, const_reference __x);
>
> with inline/hidden visibility, but not this one:
>
> template <class _ForwardIterator>
> typename enable_if  <__is_forward_iterator<_ForwardIterator>::value, void>::type
> __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
>
>
> Thanks,
>
> —
> Mehdi
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: libc++ internals visibility rational

Richard Pennington via cfe-dev
The context is that I’m working on the plan here: http://lists.llvm.org/pipermail/cfe-dev/2016-July/049985.html

Trying to remove “all" of the “always_inline”, making the public APIs hidden, and the internal APIs “internal_linkage”.

The kind of discrepancy I mentioned below puzzles me though.

— 
Mehdi

On Mar 31, 2017, at 11:49 PM, Eric Fiselier <[hidden email]> wrote:

Honestly I've been wondering about the same things.

Libc++ needs to re-evaluate it's entire approach to symbol visibility especially w.r.t ABI management.
I think a lot of the existing behavior is purely historical, and newer parts of the library just try to mimic that
regardless of QoI. In particular I'm sceptical that libc++'s use of __always_inline__ helps prevent "ABI problems".

I would love to start a discussion on this, especially if it leads to concrete example
that can be turned into test cases

/Eric


On Fri, Mar 31, 2017 at 11:57 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
Similarly with the public free template functions:


template <class _L0, class _L1>
void
lock(_L0& __l0, _L1& __l1)

and

template <class _L0, class _L1, class _L2, class ..._L3>
inline _LIBCPP_INLINE_VISIBILITY
void
lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& …__l3)



Mehdi



> On Mar 31, 2017, at 10:46 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
>
> Hi,
>
> I’m wondering about libc++ visibility for the internals of the library. For example why do we define:
>
> _LIBCPP_INLINE_VISIBILITY
>    void __construct_at_end(size_type __n, const_reference __x);
>
> with inline/hidden visibility, but not this one:
>
> template <class _ForwardIterator>
> typename enable_if  <__is_forward_iterator<_ForwardIterator>::value, void>::type
> __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
>
>
> Thanks,
>
> —
> Mehdi
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: libc++ internals visibility rational

Richard Pennington via cfe-dev
In reply to this post by Richard Pennington via cfe-dev
I think this instance is just a bug.

As it was explained to me, libc++ attempts to make it possible to statically link together two libraries that use different versions of libc++ headers. These two libraries may reference inline template functions from libc++ with different definitions, but as long as all of the out-of-line symbols remain the same and implement the same functionality and use the same struct layouts, things are supposed to "work".

With that in mind, any inline function in libc++ that isn't always_inline or internal_linkage is probably a bug.

On Fri, Mar 31, 2017 at 10:46 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
Hi,

I’m wondering about libc++ visibility for the internals of the library. For example why do we define:

_LIBCPP_INLINE_VISIBILITY
    void __construct_at_end(size_type __n, const_reference __x);

with inline/hidden visibility, but not this one:

template <class _ForwardIterator>
typename enable_if  <__is_forward_iterator<_ForwardIterator>::value, void>::type
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);


Thanks,


Mehdi

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: libc++ internals visibility rational

Richard Pennington via cfe-dev

On Apr 3, 2017, at 2:35 PM, Reid Kleckner <[hidden email]> wrote:

I think this instance is just a bug.

As it was explained to me, libc++ attempts to make it possible to statically link together two libraries that use different versions of libc++ headers. These two libraries may reference inline template functions from libc++ with different definitions, but as long as all of the out-of-line symbols remain the same and implement the same functionality and use the same struct layouts, things are supposed to "work".

With that in mind, any inline function in libc++ that isn't always_inline or internal_linkage is probably a bug.

We should be able to have “ABI stable” function as well right? 

The way I see it (with some help from Duncan) right now is that we have 5 conceptual categories for symbols. So instead of having macros like “INLINE_VISIBILITY” etc. I rather have macros that represent more accurately the category a function belongs to:

1) Symbols present and exported in the dylib, these are ABI stable. Should be marked with _LIBCPP_DLL_VIS right now.
2) Symbols that are public APIs (not starting with __), and ABI stable. These don’t have to be hidden or always_inline. I’d add a macro that would reflect this, like _LIBCPP_PUBLIC_ABISTABLE
3) Symbols that are public APIs, and not ABI stable (do these exist?). These may need to stay hidden and always_inline, or possible made internal instead? The annotation could be _LIBCPP_PUBLIC_UNSTABLE
4) Symbols that are private APIs, but ABI stable (likely rare?). We could mark them _LIBCPP_PRIVATE_ABISTABLE
5) Symbols that are private APIs, and not ABI stable. Currently always_inline/hidden, but we’d like to change these to “internal_linkage”.  We could mark them _LIBCPP_PRIVATE_UNSTABLE

This way we can expect *every* function to be decorated, and it should be fairly easy to spot a missing annotation.

And that’s just for the symbols, there is also the consideration about the type infos, vtables, etc. that I’m not totally sure about.

— 
Mehdi


On Fri, Mar 31, 2017 at 10:46 PM, Mehdi Amini via cfe-dev <[hidden email]> wrote:
Hi,

I’m wondering about libc++ visibility for the internals of the library. For example why do we define:

_LIBCPP_INLINE_VISIBILITY
    void __construct_at_end(size_type __n, const_reference __x);

with inline/hidden visibility, but not this one:

template <class _ForwardIterator>
typename enable_if  <__is_forward_iterator<_ForwardIterator>::value, void>::type
__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);


Thanks,


Mehdi

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...