Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8299709 | 8u371 | Ioi Lam | P4 | Resolved | Fixed | b02 |
See http://mail.openjdk.java.net/pipermail/hotspot-dev/2012-December/007642.html for the mail trail.
The logic in "self patching vtables" used by Class Data Sharing (CDS) is
overly complicated and involves CPU-dependent code. This RFE proposes
a way to simplify it.
See these files, especially patch_klass_vtables() in metaspaceShared.cpp
hotspot/src/share/vm/memory/metaspaceShared.cpp
hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp
hotspot/src/cpu/x86/vm/metaspaceShared_x86_32.cpp
hotspot/src/cpu/x86/vm/metaspaceShared_x86_64.cpp
hotspot/src/cpu/zero/vm/metaspaceShared_zero.cpp
hotspot/src/share/vm/memory/metaspaceShared.cpp
(..plus other CPU architectures in closed repositories)
The reasons behind the current implementation:
[1] Objects of the Metadata types (such as Klass and ConstantPool) have vtables.
In GCC this is the field <Type>::_vptr, i.e., first word in
the object.
[2] Addresses of the vtables and the methods may be different across JVM runs,
if libjvm.so is loaded at a different base address.
[3] Although all of the Metadata objects are mapped R/W in the CDS image,
at load time, we don't want to rewrite _vptr of each Metadata object
(to maximize sharing).
[4] Therefore, we redirect _vptr to our own vtables at CDS image dump time.
Then,we patch our own vtables at run time.
[5] The problem with [4] is with most C++ compilers (all?), there is no
easy way to tell the size of the vtable of a given type.
[6] We cannot safely copy more than the size of the real vtable, because the
real vtable may be at the end of the code section; reading past its end
would cause the VM to crash.
As a result, the current design of the 'self patching vtable' is to
create a vtable that's "big enough" (currently with 200 method slots).
Each slot points to a generated stub that knows the C++ type and
virtual method index of the invoked method. When the stub is invoked,
it will look up the real method and patch the vtable accordingly.
-----
The whole reason for implementing the self patching vtables in this complicated
way is [5] (the inability to get the length of the vtable).
However, it's pretty easy to get the length of the vtable in a
platform-independent way:
class InstanceKlassVTableLengthFinder: public InstanceKlass {
public:
virtual void ___end_of_vtable_marker();
};
and then just search for ___end_of_vtable_marker() from the _vptr.
With this, we can remove all the CPU-dependent code, and make HotSpot
easier to port and maintain.
The logic in "self patching vtables" used by Class Data Sharing (CDS) is
overly complicated and involves CPU-dependent code. This RFE proposes
a way to simplify it.
See these files, especially patch_klass_vtables() in metaspaceShared.cpp
hotspot/src/share/vm/memory/metaspaceShared.cpp
hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp
hotspot/src/cpu/x86/vm/metaspaceShared_x86_32.cpp
hotspot/src/cpu/x86/vm/metaspaceShared_x86_64.cpp
hotspot/src/cpu/zero/vm/metaspaceShared_zero.cpp
hotspot/src/share/vm/memory/metaspaceShared.cpp
(..plus other CPU architectures in closed repositories)
The reasons behind the current implementation:
[1] Objects of the Metadata types (such as Klass and ConstantPool) have vtables.
In GCC this is the field <Type>::_vptr, i.e., first word in
the object.
[2] Addresses of the vtables and the methods may be different across JVM runs,
if libjvm.so is loaded at a different base address.
[3] Although all of the Metadata objects are mapped R/W in the CDS image,
at load time, we don't want to rewrite _vptr of each Metadata object
(to maximize sharing).
[4] Therefore, we redirect _vptr to our own vtables at CDS image dump time.
Then,we patch our own vtables at run time.
[5] The problem with [4] is with most C++ compilers (all?), there is no
easy way to tell the size of the vtable of a given type.
[6] We cannot safely copy more than the size of the real vtable, because the
real vtable may be at the end of the code section; reading past its end
would cause the VM to crash.
As a result, the current design of the 'self patching vtable' is to
create a vtable that's "big enough" (currently with 200 method slots).
Each slot points to a generated stub that knows the C++ type and
virtual method index of the invoked method. When the stub is invoked,
it will look up the real method and patch the vtable accordingly.
-----
The whole reason for implementing the self patching vtables in this complicated
way is [5] (the inability to get the length of the vtable).
However, it's pretty easy to get the length of the vtable in a
platform-independent way:
class InstanceKlassVTableLengthFinder: public InstanceKlass {
public:
virtual void ___end_of_vtable_marker();
};
and then just search for ___end_of_vtable_marker() from the _vptr.
With this, we can remove all the CPU-dependent code, and make HotSpot
easier to port and maintain.
- backported by
-
JDK-8299709 Remove CPU-dependent code in self-patching vtables
-
- Resolved
-
- relates to
-
JDK-8290981 Enable CDS for zero builds
-
- Resolved
-