This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Strange behaviour in C++...


FWIW:  Two years ago or so I worked out a design for multiple inheritance
that might significantly reduce the incidence of non-zero adjustment
and hence the need for thunk.  The goal was an efficient way to
implement Java interface calls, but it might also apply to C++
virtual inheritance of base classes with no instance fields.

The thing to note in this context is that Java "interfaces" are
basically abstract classes with no instance fields. The tradeoff
is that Java's "interface inheritance" arguably supports the most
useful "90%" of the need multiple inhertitance.

A quick summary:  Because there are no fields, we don't need to
adjust any pointers to get at the fields - we can use the address
of the entire object as the address of the sub-part for the base
class.  This is what Java does, and it simplifies a lot of things.
However, there is still one complication:  We need to get at the
correct vtable for the base class, given a pointer to the entire
object, even though the compiler does not know the class of the
entire object.  The traditional C++ solution is to embed extra
vtable pointers in the object, but that of course is what we
must avoid.  So we need an efficient way to map from the pointer
for the entire object to the vtable for the base class.  This is
clearly possible, given RTTI.  However, we want to use a code
sequence that is constant time and small enough that it can
be inlined.  I came up with a design using some extra indexing using
helper tables;  a relatively small part of the tables are built
at link time, rather than compile time.  (This means that if new
classes are loaded dynamically using dlopen, then some tables may
have to be changed.)

I can dig up the write-up if someone wants to pursue this (it was
posted to java-discuss a few months ago).  In any case, I'm not
sure the specific implementation would be suitable for C++.  But the
basic idea is simple and general:  At link time compute a map (hash)
that for any empty abstract class and any class that inherits from
it can map a pointer to the implementing class to the abstract class
vtable, *without* adding any per-object pointers beyond the
existing shared vtable pointer.

There are some down-sides to the concept:  The main one is that calls
to abstract empty classes take a few more instructions.  On the other
hand, we save an extra vtable pointer per object per abstract empty class
it implements, plus we save useless per-object vbase pointers.  We
also seriously reduce the incidence of non-zero pointer adjustments,
which reduces the overhead of thunks.  Finally, we get increased
ABI compatibility between C++ and Java:  C++ code can call methods
given a reference to a Java interface type, and we can have G++ treat
it the same as a call given a reference to a C++ abstract empty class.
Thus a Java inheritance tree *including* interface inheritance can
be mapped to equivalent C++ classes.  This provides further unication
of the C++ and Java ABIs and object models, which helps simplify
Java, G++, LibGcj, and Gdb.

I'd love it if someone more knowledgable about C++ ABI needs could
chew on this concept, and perhaps come up with something that
works for C++ as well as Java.
-- 
	--Per Bothner
bothner@pacbell.net  per@bothner.com   http://home.pacbell.net/bothner/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]