Placement of vtables, inlines and such

Christophe de Dinechin ddd at cup.hp.com
Fri Jun 25 00:14:39 UTC 1999


From: Jason Merrill <jason at cygnus.com>
>
> Christophe mentioned the other day that the HP compiler used the  
typical
> heuristic above, and handled the case of different results by  
encoding the
> key function in the vtable name.  But this seems unnecessary when  
we can
> just choose one of multiple defns.

I think that the name of the vtable has to either contain the name  
of the class or the (mangled) name of the key function. If there is a  
key function, it does not harm to use that as the name (except that  
it makes for a slightly longer symbol), and it sometimes catches some  
broken makefiles that fail to recompile some .o file when a .h file  
they include changed :-). I don't know if catching a problem  
"sometimes" is better than "never", or if it is actually worse...

Also, HP uses COMDATs for the actual emission of the vtable,  
out-of-line copies of inline functions, some cases of template  
instantiations, etc. Our COMDAT key is the name alone. I don't think  
we can have the linker check size or whatever. Note that it's hard to  
believe that the content of a COMDAT section for code emitted by two  
different compilers would have anything in common :-)

> I propose that the ia64 base ABI be extended to provide for either  
COMDAT
> sections or garbage collection, and that we use that support for vague 
> linkage.

It looks to me like garbage collection requires one extra operation,  
namely selecting the "blessed" symbol that will not be discarded,  
right? Isn't that some other form of COMDATing? In other words, isn't  
garbage collection just an additional optimization which may be  
placed on top of COMDATs?


> I further propose that we not use heuristics to cut down the number of 
> copies ahead of time; they usually work fine, but can cause problems in 
> some situations, such as when not all of the class's members are in the 
> same symbol space.  Does the ia64 ABI provide for controlling  
which symbols
> are exported from a shared library?

As you said, "they usually work fine". In particular, without them,  
you end up emitting the same vtables again and again, which is a  
waste of time, disk space, etc. Just as a reminder, IA64 .o files are  
not exactly small. Regarding the symbol spaces, did I misunderstand,  
or are you talking about having some pathological case like (using  
Microsoft's notations :-)

	#if INCLUDED_FROM_FILE_1
	__declspec(export)
	#endif
	inline void foo() { ... }

That's just a bad idea. There may be other cases I did not think of,  
but currently, I don't see this as a real issue.

>
> A side issue: What do we want to do with dynamically-initialized  
variables?
> The same thing, or use COMMON?  I propose COMMON.

The problem is that some compiler may be smarter at inlining that  
another, and figure out that it actually can initialize it  
statically. In that case, it cannot go into COMMON (or you force that  
smart compiler to not do that optimization for binary compatibility  
reasons...). For instance:

	inline int f() { return 1; }
	static int i = f();

What is the problem with COMMON?


> A side issue is how to handle local static variables in inlines.  G++ 
> currently avoids this issue by suppressing inlining of functions with 
> local statics, if we don't want to do that, we'll need to specify a 
> mangling for the statics, and handle multiple copies like we do above. 

Side issue of side issue: you are also supposed to name string  
constants, because they are supposed to have the same address in  
different inline functions ([7.1.2]/4 :-)


Christophe




More information about the cxx-abi-dev mailing list