--- old/src/share/vm/oops/klass.cpp 2017-04-12 06:55:14.647294708 -0700 +++ new/src/share/vm/oops/klass.cpp 2017-04-12 06:55:14.471288071 -0700 @@ -497,10 +497,12 @@ // Null out class_loader_data because we don't share that yet. set_class_loader_data(NULL); + set_is_shared(); } void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { assert(is_klass(), "ensure C++ vtable is restored"); + assert(is_shared(), "must be set"); TRACE_RESTORE_ID(this); // If an exception happened during CDS restore, some of these fields may already be --- old/src/share/vm/oops/klass.hpp 2017-04-12 06:55:15.263317934 -0700 +++ new/src/share/vm/oops/klass.hpp 2017-04-12 06:55:15.079310996 -0700 @@ -563,6 +563,8 @@ void set_has_vanilla_constructor() { _access_flags.set_has_vanilla_constructor(); } bool has_miranda_methods () const { return access_flags().has_miranda_methods(); } void set_has_miranda_methods() { _access_flags.set_has_miranda_methods(); } + bool is_shared() const { return access_flags().is_shared_class(); } // shadows MetaspaceObj::is_shared)() + void set_is_shared() { _access_flags.set_is_shared_class(); } bool is_cloneable() const; void set_is_cloneable(); --- old/src/share/vm/oops/klassVtable.cpp 2017-04-12 06:55:15.867340707 -0700 +++ new/src/share/vm/oops/klassVtable.cpp 2017-04-12 06:55:15.687333920 -0700 @@ -1014,15 +1014,16 @@ void itableMethodEntry::initialize(Method* m) { if (m == NULL) return; +#ifndef PRODUCT if (MetaspaceShared::is_in_shared_space((void*)&_method) && !MetaspaceShared::remapped_readwrite()) { // At runtime initialize_itable is rerun as part of link_class_impl() // for a shared class loaded by the non-boot loader. // The dumptime itable method entry should be the same as the runtime entry. assert(_method == m, "sanity"); - } else { - _method = m; } +#endif + _method = m; } klassItable::klassItable(InstanceKlass* klass) { --- old/src/share/vm/utilities/accessFlags.hpp 2017-04-12 06:55:16.483363932 -0700 +++ new/src/share/vm/utilities/accessFlags.hpp 2017-04-12 06:55:16.299356996 -0700 @@ -64,6 +64,7 @@ JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method + JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared // Klass* and Method* flags JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000, @@ -146,6 +147,8 @@ bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; } bool has_final_method () const { return (_flags & JVM_ACC_HAS_FINAL_METHOD ) != 0; } bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; } + bool is_shared_class () const { return (_flags & JVM_ACC_IS_SHARED_CLASS ) != 0; } + // Klass* and Method* flags bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; } void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } @@ -216,6 +219,7 @@ void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); } void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); } void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); } + void set_is_shared_class() { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS); } public: // field flags