< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page

        

@@ -67,20 +67,22 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "oops/typeArrayKlass.hpp"
+#include "oops/valueKlass.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/fieldType.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/signature.hpp"
 #include "services/classLoadingService.hpp"
 #include "services/diagnosticCommand.hpp"
 #include "services/threadService.hpp"

@@ -257,13 +259,13 @@
 InstanceKlass* SystemDictionary::resolve_instance_class_or_null_helper(Symbol* class_name,
                                                                        Handle class_loader,
                                                                        Handle protection_domain,
                                                                        TRAPS) {
   assert(class_name != NULL && !FieldType::is_array(class_name), "must be");
-  if (FieldType::is_obj(class_name)) {
+  if (FieldType::is_obj(class_name) || FieldType::is_valuetype(class_name)) {
     ResourceMark rm(THREAD);
-    // Ignore wrapping L and ;.
+    // Ignore wrapping L and ;. (and Q and ; for value types);
     TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1,
                                                  class_name->utf8_length() - 2);
     return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD);
   } else {
     return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD);

@@ -284,27 +286,26 @@
   Klass* k = NULL;
   FieldArrayInfo fd;
   // dimension and object_key in FieldArrayInfo are assigned as a side-effect
   // of this call
   BasicType t = FieldType::get_array_info(class_name, fd, CHECK_NULL);
-  if (t == T_OBJECT) {
+  if (t == T_OBJECT  || t == T_VALUETYPE) {
     // naked oop "k" is OK here -- we assign back into it
     k = SystemDictionary::resolve_instance_class_or_null(fd.object_key(),
                                                          class_loader,
                                                          protection_domain,
                                                          CHECK_NULL);
     if (k != NULL) {
-      k = k->array_klass(fd.dimension(), CHECK_NULL);
+      k = k->array_klass(fd.storage_props(), fd.dimension(), CHECK_NULL);
     }
   } else {
     k = Universe::typeArrayKlassObj(t);
-    k = TypeArrayKlass::cast(k)->array_klass(fd.dimension(), CHECK_NULL);
+    k = TypeArrayKlass::cast(k)->array_klass(fd.storage_props(), fd.dimension(), CHECK_NULL);
   }
   return k;
 }
 
-
 // Must be called for any super-class or super-interface resolution
 // during class definition to allow class circularity checking
 // super-interface callers:
 //    parse_interfaces - for defineClass & jvmtiRedefineClasses
 // super-class callers:

@@ -444,10 +445,55 @@
   }
 
   return superk;
 }
 
+Klass* SystemDictionary::resolve_flattenable_field_or_fail(AllFieldStream* fs,
+                                                           Handle class_loader,
+                                                           Handle protection_domain,
+                                                           bool throw_error,
+                                                           TRAPS) {
+  Symbol* class_name = fs->signature()->fundamental_name(THREAD);
+  class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
+  ClassLoaderData* loader_data = class_loader_data(class_loader);
+  unsigned int p_hash = placeholders()->compute_hash(class_name);
+  int p_index = placeholders()->hash_to_index(p_hash);
+  bool throw_circularity_error = false;
+  PlaceholderEntry* oldprobe;
+
+  {
+    MutexLocker mu(SystemDictionary_lock, THREAD);
+    oldprobe = placeholders()->get_entry(p_index, p_hash, class_name, loader_data);
+    if (oldprobe != NULL &&
+      oldprobe->check_seen_thread(THREAD, PlaceholderTable::FLATTENABLE_FIELD)) {
+      throw_circularity_error = true;
+
+    } else {
+      placeholders()->find_and_add(p_index, p_hash, class_name, loader_data,
+                                   PlaceholderTable::FLATTENABLE_FIELD, NULL, THREAD);
+    }
+  }
+
+  Klass* klass = NULL;
+  if (!throw_circularity_error) {
+    klass = SystemDictionary::resolve_or_fail(class_name, class_loader,
+                                               protection_domain, true, THREAD);
+  } else {
+    ResourceMark rm(THREAD);
+    THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), class_name->as_C_string());
+  }
+
+  {
+    MutexLocker mu(SystemDictionary_lock, THREAD);
+    placeholders()->find_and_remove(p_index, p_hash, class_name, loader_data,
+                                    PlaceholderTable::FLATTENABLE_FIELD, THREAD);
+  }
+
+  class_name->decrement_refcount();
+  return klass;
+}
+
 void SystemDictionary::validate_protection_domain(InstanceKlass* klass,
                                                   Handle class_loader,
                                                   Handle protection_domain,
                                                   TRAPS) {
   if(!has_checkPackageAccess()) return;

@@ -661,11 +707,11 @@
 InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
                                                                 Handle class_loader,
                                                                 Handle protection_domain,
                                                                 TRAPS) {
   assert(name != NULL && !FieldType::is_array(name) &&
-         !FieldType::is_obj(name), "invalid class name");
+         !FieldType::is_obj(name) && !FieldType::is_valuetype(name), "invalid class name");
 
   EventClassLoad class_load_start_event;
 
   HandleMark hm(THREAD);
 

@@ -972,17 +1018,17 @@
     // The name refers to an array.  Parse the name.
     // dimension and object_key in FieldArrayInfo are assigned as a
     // side-effect of this call
     FieldArrayInfo fd;
     BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL));
-    if (t != T_OBJECT) {
+    if (t != T_OBJECT  && t != T_VALUETYPE) {
       k = Universe::typeArrayKlassObj(t);
     } else {
       k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD);
     }
     if (k != NULL) {
-      k = k->array_klass_or_null(fd.dimension());
+      k = k->array_klass_or_null(fd.storage_props(), fd.dimension());
     }
   } else {
     k = find(class_name, class_loader, protection_domain, THREAD);
   }
   return k;

@@ -2152,11 +2198,11 @@
     if (UseBiasedLocking && BiasedLocking::enabled()) {
       // Set biased locking bit for all loaded classes; it will be
       // cleared if revocation occurs too often for this type
       // NOTE that we must only do this when the class is initally
       // defined, not each time it is referenced from a new class loader
-      if (oopDesc::equals(k->class_loader(), class_loader())) {
+      if (oopDesc::equals(k->class_loader(), class_loader()) && !k->is_value()) {
         k->set_prototype_header(markOopDesc::biased_locking_prototype());
       }
     }
 
     // Make a new dictionary entry.

@@ -2198,19 +2244,19 @@
   if (FieldType::is_array(class_name)) {
     // For array classes, their Klass*s are not kept in the
     // constraint table. The element Klass*s are.
     FieldArrayInfo fd;
     BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL));
-    if (t != T_OBJECT) {
+    if (t != T_OBJECT && t != T_VALUETYPE) {
       klass = Universe::typeArrayKlassObj(t);
     } else {
       MutexLocker mu(SystemDictionary_lock, THREAD);
       klass = constraints()->find_constrained_klass(fd.object_key(), class_loader);
     }
     // If element class already loaded, allocate array klass
     if (klass != NULL) {
-      klass = klass->array_klass_or_null(fd.dimension());
+      klass = klass->array_klass_or_null(fd.storage_props(), fd.dimension());
     }
   } else {
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // Non-array classes are easy: simply check the constraint table.
     klass = constraints()->find_constrained_klass(class_name, class_loader);

@@ -2538,11 +2584,11 @@
     // It's a primitive.  (Void has a primitive mirror too.)
     char ch = type->char_at(0);
     assert(is_java_primitive(char2type(ch)) || ch == 'V', "");
     return Handle(THREAD, find_java_mirror_for_type(ch));
 
-  } else if (FieldType::is_obj(type) || FieldType::is_array(type)) {
+  } else if (FieldType::is_obj(type) || FieldType::is_valuetype(type) || FieldType::is_array(type)) {
 
     // It's a reference type.
     if (accessing_klass != NULL) {
       class_loader      = Handle(THREAD, accessing_klass->class_loader());
       protection_domain = Handle(THREAD, accessing_klass->protection_domain());
< prev index next >