[cxx-abi-dev] C++ ABI version 2
John McCall
rjmccall at apple.com
Wed Nov 20 05:33:31 UTC 2013
On Nov 19, 2013, at 5:57 PM, Richard Smith <richardsmith at google.com> wrote:
> There are a few things in the current ABI which are known to be suboptimal, but we cannot change because doing so would introduce an ABI break. However, vendors sometimes get an opportunity to break their ABI (or are defining a new ABI), and for some vendors, this is a very common occurrence. To this end, I think it would be valuable for the ABI document to describe what we might want to put in a 'Version 2' of the ABI; that is, a set of changes that we recommend be made whenever a vendor has a chance to introduce an ABI break.
>
> (Or perhaps this should be viewed from the opposite perspective: we could make improvements to the ABI, with an annex listing changes that old platforms must make for compatibility.)
>
> Would there be support for this idea?
Personally, I’m in favor of us generally documenting any vendor-specific deviations, as long as the vendor’s okay with it. In principle, that list of deviations could get unmanageably long, but I doubt it’d be a real issue.
> In off-line discussion with John McCall, we came up with the following list of potential changes that might be made (sorry if I forgot any):
>
> * Simplify case 2b in non-POD class layout.
> * Make constructors and destructors return 'this' instead of returning 'void', in order to allow callers to avoid a reload in common cases and to allow more tail calls.
> * Make virtual functions that are defined as 'inline' not be key functions
Credit the good folks at ARM for these two ideas.
> * Fix the bug that -1 is both the null pointer-to-data-member value and also a valid value of a pointer-to-data-member (could use SIZE_MIN instead)
> * Relax the definition of POD used in the ABI, in order to allow more class types to be passed in registers
POD-ness doesn't affect what can be passed in registers; that’s just about the copy constructor(s) and destructor.
Making a type POD in the ABI means that we can’t allocate subobjects of subclasses into its tail-padding. This is, at least, in theory, a tradeoff:
- The downside is that derived classes might get larger.
- The upside is that assignments into an opaque T& can copy sizeof(T) bytes instead of dsize(T). When those quantities differ, copying sizeof(T) is generally faster because a round number of words can be copied in fewer instructions; e.g. 24 bytes (8-byte aligned) can be done in three 64-bit stores, whereas 22 bytes (but still 8-byte aligned) requires two 64-bit stores, a 32-bit store, and a 16-bit store.
I would argue that it’s abstractly more likely that trivially-copyable type will be assigned at some point than that it will be used as a base class, but I don’t have empirical evidence for that.
> Are there any other things that it would make sense to change in a version 2 of the ABI?
We could consider giving standard substitutions to some of the newer library features, like std::shared_ptr and std::unique_ptr. I don’t know if standard substitutions still matter to other people; Apple’s committed to libc++, which intentionally subverts them with inline namespaces.
> Also, would there be any support for documenting common deviations from the ABI that platform vendors might want to consider when specifying their own ABIs? In addition to some of the above, this would also include:
>
> * Representation of pointers-to-member-functions (in particular, the current representation assumes that the lowest bit of a function pointer is unused, which isn't true in general)
> * Representation of guard variables (some platforms use the native word size rather than forcing this to be 64 bits wide)
I would actually call this one a recommended change. As far as I know, making them 64 bits on all platforms was just an Itanium assumption sneaking in. I don’t know of any clever locking strategies that vitally require two pointers of data.
John.
More information about the cxx-abi-dev
mailing list