# HG changeset patch # User coleenp # Date 1346890088 14400 # Node ID fa6e618671d7a102609096fd914c1479571eaed8 # Parent 78b56e53050e7aed371ec8cfa2982d14cd2b5933 7195867: NPG: SAJDI tests fail with sun.jvm.hotspot.types.WrongTypeException: No suitable match for type Summary: Need to restore the vtable in metadata when we restore the type from the shared archive. Reviewed-by: acorn, jcoomes, jmasa, jrose diff -r 78b56e53050e -r fa6e618671d7 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Wed Sep 05 10:18:37 2012 -0700 +++ b/src/share/vm/classfile/systemDictionary.cpp Wed Sep 05 20:08:08 2012 -0400 @@ -1953,7 +1953,7 @@ // 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 -r 78b56e53050e -r fa6e618671d7 src/share/vm/memory/metaspaceShared.cpp --- a/src/share/vm/memory/metaspaceShared.cpp Wed Sep 05 10:18:37 2012 -0700 +++ b/src/share/vm/memory/metaspaceShared.cpp Wed Sep 05 20:08:08 2012 -0400 @@ -153,9 +153,9 @@ // // 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 -r 78b56e53050e -r fa6e618671d7 src/share/vm/oops/constantPool.cpp --- a/src/share/vm/oops/constantPool.cpp Wed Sep 05 10:18:37 2012 -0700 +++ b/src/share/vm/oops/constantPool.cpp Wed Sep 05 20:08:08 2012 -0400 @@ -152,6 +152,10 @@ // 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 -r 78b56e53050e -r fa6e618671d7 src/share/vm/oops/constantPool.hpp --- a/src/share/vm/oops/constantPool.hpp Wed Sep 05 10:18:37 2012 -0700 +++ b/src/share/vm/oops/constantPool.hpp Wed Sep 05 20:08:08 2012 -0400 @@ -643,6 +643,11 @@ 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 -r 78b56e53050e -r fa6e618671d7 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Wed Sep 05 10:18:37 2012 -0700 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Sep 05 20:08:08 2012 -0400 @@ -2165,6 +2165,8 @@ 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 -r 78b56e53050e -r fa6e618671d7 src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Wed Sep 05 10:18:37 2012 -0700 +++ b/src/share/vm/oops/method.hpp Wed Sep 05 20:08:08 2012 -0400 @@ -168,9 +168,16 @@ 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; }