Determining the size of C++ vtables (original) (raw)
Thomas Stüfe thomas.stuefe at gmail.com
Fri Feb 24 07:17:28 UTC 2017
- Previous message: Determining the size of C++ vtables
- Next message: Determining the size of C++ vtables
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi Ioi,
After reading through the original mailthread referenced in the bug report, the only reason the "just copy enough (200) slots from the vtable in libjvm.so to the vtable in the image" approach does not work for you is that you are afraid of hitting unmapped memory? If I understand it correctly.
If that is the case, why not copy 200 slots with SafeFetch and stop at the first error? That should not incur much additional costs as long as you do not hit an unmapped area, in which case you'd stop anyway.
That way you make yourself a bit less dependent on compiler internals. I agree that your approach is more elegant, though.
Kind Regards, Thomas
On Fri, Feb 24, 2017 at 4:55 AM, Ioi Lam <ioi.lam at oracle.com> wrote:
On 2/23/17 7:47 PM, Ioi Lam wrote: Hi,
I am working on https://bugs.openjdk.java.net/browse/JDK-8005165 (Remove CPU-dependent code in self-patching vtables), I need a way find out the size of a C++ vtable. I ended up doing this:
// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. // (In GCC this is the field ::vptr, i.e., first word in the object.) // // Addresses of the vtables and the methods may be different across JVM runs, // if libjvm.so is dynamically loaded at a different base address. // // To ensure that the Metadata objects in the CDS archive always have the correct vtable: // // + at dump time: we redirect the vptr to point to our own vtables inside // the CDS image // + at run time: we clone the actual contents of the vtables from libjvm.so // into our own tables. // // To determine the size of the vtable for each type, we use the following // trick by declaring 2 subclasses: // // class CppVtabTesterA: public InstanceKlass { // virtual int lastvirtualmethod() {return 1;} // }; // class CppVtabTesterB: public InstanceKlass { // virtual void* lastvirtualmethod() {return NULL}; // }; // // CppVtabTesterA and CppVtabTesterB's vtables have the following properties: // - Their size (N+1) is exactly one more than the size of InstanceKlass's vtable (N) // - The first N entries have are exactly the same as in InstanceKlass's vtable. // - Their last entry is different. // // So to determine the value of N, we just walk CppVtabTesterA and CppVtabTesterB's tables // and find the first entry that's different Could anyone comment if this is acceptable? I know it's not 100% portable (C++ doesn't specify where to find the vtable, or what's inside), but my assumptions is the same as the existing code. I.e., vptr is a pointer located at offset 0 of the object, and it points to a one-dimensional array. So at least it's not any worse than before? Thanks - Ioi By the way, I first tried having only a single "tester" class and walk the vtable to look for &lastvirtualmethod, but the C++ compiler told me that taking the address of a non-static function is not allowed ..... so I ended up creating two tester classes and checking their differences.
- Previous message: Determining the size of C++ vtables
- Next message: Determining the size of C++ vtables
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]