--- old/src/hotspot/share/oops/constantPool.cpp 2019-03-11 14:26:12.550355067 +0100 +++ new/src/hotspot/share/oops/constantPool.cpp 2019-03-11 14:26:12.322355070 +0100 @@ -47,6 +47,7 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayOop.inline.hpp" +#include "oops/valueArrayKlass.hpp" #include "runtime/fieldType.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" @@ -210,7 +211,7 @@ case JVM_CONSTANT_Class: case JVM_CONSTANT_UnresolvedClass: case JVM_CONSTANT_UnresolvedClassInError: - // All of these should have been reverted back to ClassIndex before calling + // All of these should have been reverted back to Unresolved before calling // this function. ShouldNotReachHere(); #endif @@ -234,10 +235,11 @@ // The interpreter assumes when the tag is stored, the klass is resolved // and the Klass* non-NULL, so we need hardware store ordering here. + jbyte qdesc_bit = name->is_Q_signature() ? (jbyte)JVM_CONSTANT_QDESC_BIT : 0; if (k != NULL) { - release_tag_at_put(class_index, JVM_CONSTANT_Class); + release_tag_at_put(class_index, JVM_CONSTANT_Class | qdesc_bit); } else { - release_tag_at_put(class_index, JVM_CONSTANT_UnresolvedClass); + release_tag_at_put(class_index, JVM_CONSTANT_UnresolvedClass | qdesc_bit); } } @@ -442,6 +444,12 @@ } } +void check_is_value_type(Klass* k, TRAPS) { + if (!k->is_value()) { + THROW(vmSymbols::java_lang_IncompatibleClassChangeError()); + } +} + Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int which, bool save_resolution_error, TRAPS) { assert(THREAD->is_Java_thread(), "must be a Java thread"); @@ -476,6 +484,11 @@ Handle mirror_handle; Symbol* name = this_cp->symbol_at(name_index); + bool value_type_signature = false; + if (name->is_Q_signature()) { + name = name->fundamental_name(THREAD); + value_type_signature = true; + } Handle loader (THREAD, this_cp->pool_holder()->class_loader()); Handle protection_domain (THREAD, this_cp->pool_holder()->protection_domain()); @@ -485,6 +498,9 @@ JvmtiHideSingleStepping jhss(javaThread); k = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD); } // JvmtiHideSingleStepping jhss(javaThread); + if (value_type_signature) { + name->decrement_refcount(); + } if (!HAS_PENDING_EXCEPTION) { // preserve the resolved klass from unloading @@ -493,6 +509,22 @@ verify_constant_pool_resolve(this_cp, k, THREAD); } + if (!HAS_PENDING_EXCEPTION && value_type_signature) { + check_is_value_type(k, THREAD); + } + + if (!HAS_PENDING_EXCEPTION) { + Klass* bottom_klass = NULL; + if (k->is_objArray_klass()) { + bottom_klass = ObjArrayKlass::cast(k)->bottom_klass(); + assert(bottom_klass != NULL, "Should be set"); + assert(bottom_klass->is_instance_klass() || bottom_klass->is_typeArray_klass(), "Sanity check"); + } else if (k->is_valueArray_klass()) { + bottom_klass = ValueArrayKlass::cast(k)->element_klass(); + assert(bottom_klass != NULL, "Should be set"); + } + } + // Failed to resolve class. We must record the errors so that subsequent attempts // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). if (HAS_PENDING_EXCEPTION) { @@ -518,7 +550,11 @@ // The interpreter assumes when the tag is stored, the klass is resolved // and the Klass* stored in _resolved_klasses is non-NULL, so we need // hardware store ordering here. - this_cp->release_tag_at_put(which, JVM_CONSTANT_Class); + jbyte tag = JVM_CONSTANT_Class; + if (this_cp->tag_at(which).is_Qdescriptor_klass()) { + tag |= JVM_CONSTANT_QDESC_BIT; + } + this_cp->release_tag_at_put(which, tag); return k; }