RFR[S] 8005165 Platform-independent C++ vtables for CDS (original) (raw)

Ioi Lam ioi.lam at oracle.com
Wed Mar 1 02:25:24 UTC 2017


https://bugs.openjdk.java.net/browse/JDK-8005165 http://cr.openjdk.java.net/~iklam/jdk10/8005165-platform-independent-cds-vtable.v02/

Hi,

This is the official review (follow up of the "Determining the size of C++ vtables" thread on hotspot-dev at openjdk.java.net).

The new code has the same assumption as the existing code in JDK 10: for a C++ object that contains virtual methods (e.g., ConstantPool), we assume the first intptr_t slot of the object is a _vptr, which points to a vtable, which consists of no more than 150 intptr_t's.

ConstantPool*p -->[ _vptr ] -------> [ vtable slot 0 ] [ field #0 ] [ vtable slot 1 ] [ field #1 ] [ vtable slot 2 ] [ field #2 ] [ vtable slot 3 ] [ .... ] [ vtable slot 4] [ vtable slot 5 ] [ ... ]

Per Thomas Stüfe's advice, I don't try to determine the size of the vtable (as that would add one more compiler requirement where new virtual methods added by a subclass must be placed at a higher offset in the vtable).

Instead, I have added code in non-product builds to ensure that the vtables are no longer than 150 entries. You can run with "-XX:+PrintSharedSpaces -Xshare:dump" to print out the actual size of the vtables for your particular platform:

ConstantPool has 12 virtual methods InstanceKlass has 113 virtual methods InstanceClassLoaderKlass has 113 virtual methods InstanceMirrorKlass has 113 virtual methods InstanceRefKlass has 113 virtual methods Method has 12 virtual methods ObjArrayKlass has 114 virtual methods TypeArrayKlass has 114 virtual methods

As mentioned in the code comments, if you have an esoteric C++ compiler, the verify_sufficient_size() function will probably fail, but hopefully that would give you some hints for porting this code.

To avoid accidentally touching an unmapped page, the code uses SafeFetchN for copying the vtable contents, and would shrink the vtable to less than 150 entries if necessary. I can't test this for real, but I've added some code to simulate an error:

 for (int i=0; i<n; i++) {
   const intptr_t bad = intptr_t(0xdeadbeef);
   intptr_t num = SafeFetchN(&srcvtab[i], bad);
   if (num == bad
       // || i > 120 /* uncomment this line to test */
       ) {
     _info->set_vtab_size(i-1);
     break;
   }
   dstvtab[i] = num;
 }

Results:

Thanks



More information about the hotspot-dev mailing list