diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp index 4843c1f2078c403049d4d44cfef9003c015e648d..9e06dcb4f1af00e42dccb7577068d97e40059501 100644 --- a/src/share/vm/classfile/systemDictionary.cpp +++ b/src/share/vm/classfile/systemDictionary.cpp @@ -1953,7 +1953,7 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) { // Initialize the constant pool for the Object_class InstanceKlass* ik = InstanceKlass::cast(Object_klass()); ik->constants()->restore_unshareable_info(CHECK); - initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK); + initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK); } else { initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK); } diff --git a/src/share/vm/memory/metaspaceShared.cpp b/src/share/vm/memory/metaspaceShared.cpp index 9c4d87e676cfdf99229c9a9997ef46df4ed6cd0d..e5553ffc6019f0833c96caec9c527b6af91a0b5b 100644 --- a/src/share/vm/memory/metaspaceShared.cpp +++ b/src/share/vm/memory/metaspaceShared.cpp @@ -153,9 +153,9 @@ static void calculate_fingerprints() { // // Execution time: // First virtual method call for any object of these metadata types: -// 1. object->klass->klass_part -// 2. vtable entry for that klass_part points to the jump table entries -// 3. branches to common_code with %O0/klass_part, %L0: Klass index <<8 + method index +// 1. object->klass +// 2. vtable entry for that klass points to the jump table entries +// 3. branches to common_code with %O0/klass, %L0: Klass index <<8 + method index // 4. common_code: // Get address of new vtbl pointer for this Klass from updated table // Update new vtbl pointer in the Klass: future virtual calls go direct diff --git a/src/share/vm/oops/constantPool.cpp b/src/share/vm/oops/constantPool.cpp index a201f336b2dbbce6f4056a4a4a67995b0305139d..b708e1ed36f145222f326c2f6d590d03e2269c7f 100644 --- a/src/share/vm/oops/constantPool.cpp +++ b/src/share/vm/oops/constantPool.cpp @@ -152,6 +152,10 @@ void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data, // CDS support. Create a new resolved_references array. void ConstantPool::restore_unshareable_info(TRAPS) { + + // restore the C++ vtable from the shared archive + restore_vtable(); + if (SystemDictionary::Object_klass_loaded()) { // Recreate the object array and add to ClassLoaderData. int map_length = resolved_reference_length(); diff --git a/src/share/vm/oops/constantPool.hpp b/src/share/vm/oops/constantPool.hpp index 90d2bcf0b33f031678d39eb19807b0ca931dd614..d290f003da370d467edab3bfae3d57d42a58fec1 100644 --- a/src/share/vm/oops/constantPool.hpp +++ b/src/share/vm/oops/constantPool.hpp @@ -643,6 +643,11 @@ class ConstantPool : public Metadata { void remove_unshareable_info(); void restore_unshareable_info(TRAPS); bool resolve_class_constants(TRAPS); + // The ConstantPool vtable is restored by this call when the ConstantPool is + // in the shared archive. See patch_klass_vtables() in metaspaceShared.cpp for + // all the gory details. SA, dtrace and pstack helpers distinguish metadata + // by their vtable. + void restore_vtable() { guarantee(is_constantPool(), "vtable restored by this call"); } private: enum { _no_index_sentinel = -1, _possible_index_sentinel = -2 }; diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index 7a2e4a37059dc96387e0e48a3c171c55a8caf740..93fc1cb0fa9a8d1df472bd6e37c3f2293cb59f05 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -2165,6 +2165,8 @@ void InstanceKlass::restore_unshareable_info(TRAPS) { for (int index2 = 0; index2 < num_methods; ++index2) { methodHandle m(THREAD, methods->at(index2)); m()->link_method(m, CHECK); + // restore method's vtable by calling a virtual function + m->restore_vtable(); } if (JvmtiExport::has_redefined_a_class()) { // Reinitialize vtable because RedefineClasses may have changed some diff --git a/src/share/vm/oops/method.hpp b/src/share/vm/oops/method.hpp index 2656b2cfecfd79bfec05c23f35aa4200e0c6e45b..66dfbae3a6c90d52a28afd6e88cb2883acdffa69 100644 --- a/src/share/vm/oops/method.hpp +++ b/src/share/vm/oops/method.hpp @@ -168,9 +168,16 @@ class Method : public Metadata { TRAPS); Method() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); } + + // The Method vtable is restored by this call when the Method is in the + // shared archive. See patch_klass_vtables() in metaspaceShared.cpp for + // all the gory details. SA, dtrace and pstack helpers distinguish metadata + // by their vtable. + void restore_vtable() { guarantee(is_method(), "vtable restored by this call"); } bool is_method() const volatile { return true; } // accessors for instance variables + ConstMethod* constMethod() const { return _constMethod; } void set_constMethod(ConstMethod* xconst) { _constMethod = xconst; }