Hello all, I am currently working on an ARM embedded project with very significant size constraints. When disassembling an executable I noticed a non-insignificant amount of space is wasted by vtables.
I am currently cross compiling with arm-none-eabi-g++ version 14.2.0 and using the following flags (among others): -fno-exceptions -fno-rtti. This is a random vtable i got from a .class file: Vtable for std::bad_alloc std::bad_alloc::_ZTVSt9bad_alloc: 5 entries 0 (int (*)(...))0 4 (int (*)(...))0 8 (int (*)(...))std::bad_alloc::~bad_alloc 12 (int (*)(...))std::bad_alloc::~bad_alloc 16 (int (*)(...))std::bad_alloc::wha Even though RTTI is disabled, and therefore dynamic_cast is disabled, the vtable still has both a pointer to base and a pointer to typeinfo. Even though they are both null. As far as I understand it both the pointer to base and typeinfo are necessary to enable dynamic_cast, since this is disabled it should be possible to get rid of these two pointers? Am I correct? Even so the typeinfo pointer is completely redundant. Getting rid of these two entries in all vtables would be very good, as doing so would lead to about a ~1.5% code size decrease in my 64k project. I have tried to make a quick and dirty patch by modifying the following in class.cc: static void build_rtti_vtbl_entries(tree binfo, vtbl_init_data *vid) { tree b; tree t; tree offset; tree decl; tree init; t = BINFO_TYPE(vid->rtti_binfo); /* To find the complete object, we will first convert to our most primary base, and then add the offset in the vtbl to that value. */ b = most_primary_binfo(binfo); offset = size_diffop_loc(input_location, BINFO_OFFSET(vid->rtti_binfo), BINFO_OFFSET(b)); /* The second entry is the address of the typeinfo object. */ /* MODIFIED - only add the entry if rtti is enabled */ if (flag_rtti) { decl = build_address(get_tinfo_decl(t)); /* Convert the declaration to a type that can be stored in the vtable. */ init = build_nop(vfunc_ptr_type_node, decl); CONSTRUCTOR_APPEND_ELT(vid->inits, NULL_TREE, init); } /* Add the offset-to-top entry. It comes earlier in the vtable than the typeinfo entry. Convert the offset to look like a function pointer, so that we can put it in the vtable. */ init = build_nop(vfunc_ptr_type_node, offset); CONSTRUCTOR_APPEND_ELT(vid->inits, NULL_TREE, init); } i have also modified vid.index in build_vtbl_initializer vid.index = ssize_int(flag_rtti ? -3 : -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); This seems to work and gcc compiles. Although I have not tested the code it generates yet. One problem is that it breaks the build for libsupc++, as it uses typeid. Is there a way to build libsupc++ with -fno-rtti? Otherwise is it possible to build libstdc++ without libsupc++? Finally my goal would be to remove the offset-to-top entry. Just commenting it out in build_rtti_vtbl_entries breaks quite a few things during runtime as vid->inits remains empty. Any pointers for any other modifications I should make? Finally, would it be possible to implement this in a plugin rather than modifying GCC itself? Thank you all in advance, Luigi Sciolla