[cxx-abi-dev] What thunks are needed?
Nathan Sidwell
nathan at codesourcery.com
Wed Jun 6 12:51:27 UTC 2001
Jason Merrill wrote:
>
> Consider:
>
> class A { virtual void f (); };
> class B1 : virtual public A { virtual void f (); };
> class B2 : virtual public A { virtual void f (); };
> class C: public B1, public B2 { virtual void f (); };
>
> The ABI spec currently says that we need a thunk for every base, period.
> Clearly this is wrong; we only need thunks for bases which define the
> function (i.e. vtables for them to go in). Furthermore, we only need one
> thunk per adjustment, since that's what is mangled. Nor do we need thunks
> that adjust by 0; we can just point to the function itself. I'll write up
Agreed.
> So: For C::f, we need a virtual thunk for A, no thunk for B1, and a
> non-virtual thunk for B2.
Disagree.
C::f needs a virtual thunk for A, no thunk for B1 no thunk for B2.
In C's vtable there will be a subvtable for B1 which contains a sub
vtable for A. There will be a secondary vtable for B2, which will
contain a sub vtable for the A base of B2. There is no A base inside
the B2 base in an object, but B2's vtable will need space allocating
as if there was one. Also it has to be set up correctly, so that if
we have a pointer to the B2 base in C, a call to f will correctly
adjust. (As B2 also defines an f, we don't have to convert the pointer
down to an A * before the virtual function call.)
> But it occurs to me that since the B2 vtable
> already has a vcall slot for f, we can use the virtual thunk there, too,
> so we only really need one thunk.
agreed.
> Thoughts? The current g++ implementation doesn't generate the non-virtual
> thunk, so this change would actually improve compatibility between a
The current g++ implementation is wrong in this regard. I've
just fixed some stuff concerning nearly-empty virtual primary base
classes that g++ was getting wrong. Mark's looking at that patch
at the moment, and, if he doesn't find anything amiss, it'll go in
tomorrow.
This is what g++ currently thinks C's vtable should be
Vtable for C
C::_ZTV1C: 10 entries
0 0
4 0
8 0
12 &_ZTI1C
16 C::_ZTv0_n12_N1C1fEv
20 -4
24 0 <- vcall adjust from B2 to C claimed to be zero
28 -4
32 &_ZTI1C
36 C::_ZTvn4_n12_N1C1fEv <- const adjust of -4 then virt adjust
here is what C's vtable should look like (and does with my patch)
Vtable for C
C::_ZTV1C: 10 entries
0 0
4 0
8 0
12 &_ZTI1C
16 C::_ZTv0_n12_N1C1fEv
20 -4
24 -4 <- vcall adjust from B2 to C is -4
28 -4
32 &_ZTI1C
36 C::_ZTv0_n12_N1C1fEv <- virtual adjust
I agree with your conclusion, but not with your intermediate step of
the B2 vtable in C being permitted to have a constant adjusting thunk.
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan at codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan at acm.org
More information about the cxx-abi-dev
mailing list