How to get "direct" function pointer to a virtual member function?

Viewed 1681

I am working on an embedded platform which doesn't cope very well with dynamic code (no speculative / OOO execution at all). On this platform I call a virtual member function on the same object quite often, however the compiler fails to optimize the vtable-lookup away, as it doesn't seem to recognize the lookup is only required for the first invocation.

Therefore I wonder: Is there a manual way to devirtualize a virtual member function of a C++ class in order to get a function-pointer which points directly to the resolved address? I had a look at C++ function pointers, but since they seem to require a type specified, I guess this won`t work out.

Thank you in advance

3 Answers

Yes, this is possible in a way that works at least with MSVC, GCC and Clang.

I was also looking for how to do this, and here is a blog post I found that explains it in detail: https://medium.com/@calebleak/fast-virtual-functions-hacking-the-vtable-for-fun-and-profit-25c36409c5e0

Taking the code from there, in short, this is what you need to do. This function works for all objects:

template <typename T>
void** GetVTable(T* obj) {
  return *((void***)obj);
}

And then to get a direct function pointer to the first virtual function of the class, you do this:

typedef void(VoidMemberFn)(void*);

VoidMemberFn* fn = (VoidMemberFn*)GetVTable<BaseType>(my_obj_ptr)[0];

// ... sometime later

fn(my_obj_ptr);

So it's quite easy actually.

Related