< prev index next >

src/hotspot/share/oops/constantPool.cpp

Print this page

        

@@ -47,10 +47,11 @@
 #include "oops/instanceKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #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"
 #include "runtime/javaCalls.hpp"
 #include "runtime/signature.hpp"

@@ -210,11 +211,11 @@
       break;
 #ifndef PRODUCT
     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,14 +235,15 @@
   Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
   OrderAccess::release_store(adr, k);
 
   // 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_QDescBit : 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);
   }
 }
 
 // Unsafe anonymous class support:
 void ConstantPool::klass_at_put(int class_index, Klass* k) {

@@ -251,10 +253,11 @@
   Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
   OrderAccess::release_store(adr, k);
 
   // The interpreter assumes when the tag is stored, the klass is resolved
   // and the Klass* non-NULL, so we need hardware store ordering here.
+  assert(!k->name()->is_Q_signature(), "Q-type without JVM_CONSTANT_QDescBit");
   release_tag_at_put(class_index, JVM_CONSTANT_Class);
 }
 
 #if INCLUDE_CDS_JAVA_HEAP
 // Archive the resolved references

@@ -451,10 +454,16 @@
                  k->external_name());
     }
   }
 }
 
+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");
   JavaThread* javaThread = (JavaThread*)THREAD;
 

@@ -485,27 +494,51 @@
     ShouldNotReachHere();
   }
 
   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());
 
   Klass* k;
   {
     // Turn off the single stepping while doing class resolution
     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
     mirror_handle = Handle(THREAD, k->java_mirror());
     // Do access check for klasses
     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) {
     if (save_resolution_error) {
       save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);

@@ -527,11 +560,15 @@
   Klass** adr = this_cp->resolved_klasses()->adr_at(resolved_klass_index);
   OrderAccess::release_store(adr, k);
   // 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_QDescBit;
+  }
+  this_cp->release_tag_at_put(which, tag);
   return k;
 }
 
 
 // Does not update ConstantPool* - to avoid any exception throwing. Used

@@ -1844,10 +1881,16 @@
         idx1 = Bytes::get_Java_u2(bytes);
         printf("class        #%03d", idx1);
         ent_size = 2;
         break;
       }
+      case (JVM_CONSTANT_Class | JVM_CONSTANT_QDescBit): {
+        idx1 = Bytes::get_Java_u2(bytes);
+        printf("qclass        #%03d", idx1);
+        ent_size = 2;
+        break;
+      }
       case JVM_CONSTANT_String: {
         idx1 = Bytes::get_Java_u2(bytes);
         printf("String       #%03d", idx1);
         ent_size = 2;
         break;

@@ -1886,10 +1929,14 @@
       }
       case JVM_CONSTANT_UnresolvedClass: {
         printf("UnresolvedClass: %s", WARN_MSG);
         break;
       }
+      case (JVM_CONSTANT_UnresolvedClass | JVM_CONSTANT_QDescBit): {
+        printf("UnresolvedQClass: %s", WARN_MSG);
+        break;
+      }
       case JVM_CONSTANT_UnresolvedClassInError: {
         printf("UnresolvedClassInErr: %s", WARN_MSG);
         break;
       }
       case JVM_CONSTANT_StringIndex: {

@@ -2057,10 +2104,11 @@
         break;
       }
       case JVM_CONSTANT_Class:
       case JVM_CONSTANT_UnresolvedClass:
       case JVM_CONSTANT_UnresolvedClassInError: {
+        assert(!tag_at(idx).is_Qdescriptor_klass(), "Failed to encode QDesc");
         *bytes = JVM_CONSTANT_Class;
         Symbol* sym = klass_name_at(idx);
         idx1 = tbl->symbol_to_value(sym);
         assert(idx1 != 0, "Have not found a hashtable entry");
         Bytes::put_Java_u2((address) (bytes+1), idx1);
< prev index next >