Merge
authordcubed
Fri, 20 Jun 2014 12:45:24 -0700
changeset 25329 462ba8f4a090
parent 25081 1e763491a589 (current diff)
parent 25327 8b34977169da (diff)
child 25330 379e432f47a0
Merge
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -512,24 +512,9 @@
   } else {
     // Check if it's resolved if it's not a symbol constant pool entry.
     klass = KlassHandle(THREAD, ConstantPool::klass_at_if_loaded(cpool, index));
-
+    // Try to look it up by name.
   if (klass.is_null()) {
-    // The klass has not been inserted into the constant pool.
-    // Try to look it up by name.
-    {
-      // We have to lock the cpool to keep the oop from being resolved
-      // while we are accessing it.
-        MonitorLockerEx ml(cpool->lock());
-      constantTag tag = cpool->tag_at(index);
-      if (tag.is_klass()) {
-        // The klass has been inserted into the constant pool
-        // very recently.
-        klass = KlassHandle(THREAD, cpool->resolved_klass_at(index));
-      } else {
-        assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag");
-        klass_name = cpool->unresolved_klass_at(index);
-      }
-    }
+      klass_name = cpool->klass_name_at(index);
   }
   }
 
--- a/hotspot/src/share/vm/ci/ciReplay.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -686,7 +686,7 @@
       switch (cp->tag_at(i).value()) {
         case JVM_CONSTANT_UnresolvedClass: {
           if (tag == JVM_CONSTANT_Class) {
-            tty->print_cr("Resolving klass %s at %d", cp->unresolved_klass_at(i)->as_utf8(), i);
+            tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
             Klass* k = cp->klass_at(i, CHECK);
           }
           break;
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -510,7 +510,7 @@
     jbyte tag = cp->tag_at(index).value();
     switch (tag) {
       case JVM_CONSTANT_UnresolvedClass: {
-        Symbol*  class_name = cp->unresolved_klass_at(index);
+        Symbol*  class_name = cp->klass_name_at(index);
         // check the name, even if _cp_patches will overwrite it
         verify_legal_class_name(class_name, CHECK_(nullHandle));
         break;
@@ -3161,7 +3161,7 @@
       if (_need_verify)
         is_array = super_klass->oop_is_array();
     } else if (_need_verify) {
-      is_array = (_cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
+      is_array = (_cp->klass_name_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
     }
     if (_need_verify) {
       guarantee_property(!is_array,
@@ -3855,7 +3855,7 @@
     "Invalid this class index %u in constant pool in class file %s",
     this_class_index, CHECK_(nullHandle));
 
-  Symbol*  class_name  = cp->unresolved_klass_at(this_class_index);
+  Symbol*  class_name  = cp->klass_name_at(this_class_index);
   assert(class_name != NULL, "class_name can't be null");
 
   // It's important to set parsed_name *before* resolving the super class.
@@ -4139,8 +4139,8 @@
     }
 
     // Allocate mirror and initialize static fields
-    java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
-
+    java_lang_Class::create_mirror(this_klass, class_loader, protection_domain,
+                                   CHECK_(nullHandle));
 
     // Generate any default methods - default methods are interface methods
     // that have a default implementation.  This is new with Lambda project.
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri Jun 20 12:45:24 2014 -0700
@@ -187,8 +187,6 @@
   JNIHandleBlock* handles() const;
   void set_handles(JNIHandleBlock* handles);
 
-  Mutex* metaspace_lock() const { return _metaspace_lock; }
-
   // GC interface.
   void clear_claimed()          { _claimed = 0; }
   bool claimed() const          { return _claimed == 1; }
@@ -216,6 +214,8 @@
     return _the_null_class_loader_data;
   }
 
+  Mutex* metaspace_lock() const { return _metaspace_lock; }
+
   bool is_anonymous() const { return _is_anonymous; }
 
   static void init_null_class_loader_data() {
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -558,7 +558,7 @@
       }
     }
   }
-  create_mirror(k, Handle(NULL), CHECK);
+  create_mirror(k, Handle(NULL), Handle(NULL), CHECK);
 }
 
 void java_lang_Class::initialize_mirror_fields(KlassHandle k,
@@ -578,7 +578,8 @@
   InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK);
 }
 
-void java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
+void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
+                                    Handle protection_domain, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
   // Use this moment of initialization to cache modifier_flags also,
   // to support Class.getModifiers().  Instance classes recalculate
@@ -633,6 +634,9 @@
       }
     }
 
+    // set the classLoader field in the java_lang_Class instance
+    set_class_loader(mirror(), class_loader());
+
     // Setup indirection from klass->mirror last
     // after any exceptions can happen during allocations.
     if (!k.is_null()) {
@@ -694,6 +698,18 @@
 }
 
 
+void java_lang_Class::set_class_loader(oop java_class, oop loader) {
+  // jdk7 runs Queens in bootstrapping and jdk8-9 has no coordinated pushes yet.
+  if (_class_loader_offset != 0) {
+    java_class->obj_field_put(_class_loader_offset, loader);
+  }
+}
+
+oop java_lang_Class::class_loader(oop java_class) {
+  assert(_class_loader_offset != 0, "must be set");
+  return java_class->obj_field(_class_loader_offset);
+}
+
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
   // This should be improved by adding a field at the Java level or by
   // introducing a new VM klass (see comment in ClassFileParser)
@@ -853,6 +869,12 @@
   compute_optional_offset(classRedefinedCount_offset,
                           klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature());
 
+  // Needs to be optional because the old build runs Queens during bootstrapping
+  // and jdk8-9 doesn't have coordinated pushes yet.
+  compute_optional_offset(_class_loader_offset,
+                 klass_oop, vmSymbols::classLoader_name(),
+                 vmSymbols::classloader_signature());
+
   CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
 }
 
@@ -3073,6 +3095,7 @@
 int java_lang_Class::_array_klass_offset;
 int java_lang_Class::_oop_size_offset;
 int java_lang_Class::_static_oop_field_count_offset;
+int java_lang_Class::_class_loader_offset;
 int java_lang_Class::_protection_domain_offset;
 int java_lang_Class::_init_lock_offset;
 int java_lang_Class::_signers_offset;
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri Jun 20 12:45:24 2014 -0700
@@ -240,19 +240,23 @@
   static int _protection_domain_offset;
   static int _init_lock_offset;
   static int _signers_offset;
+  static int _class_loader_offset;
 
   static bool offsets_computed;
   static int classRedefinedCount_offset;
+
   static GrowableArray<Klass*>* _fixup_mirror_list;
 
   static void set_init_lock(oop java_class, oop init_lock);
   static void set_protection_domain(oop java_class, oop protection_domain);
+  static void set_class_loader(oop java_class, oop class_loader);
   static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
  public:
   static void compute_offsets();
 
   // Instance creation
-  static void create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
+  static void create_mirror(KlassHandle k, Handle class_loader,
+                            Handle protection_domain, TRAPS);
   static void fixup_mirror(KlassHandle k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
   // Conversion
@@ -290,6 +294,8 @@
   static objArrayOop  signers(oop java_class);
   static void set_signers(oop java_class, objArrayOop signers);
 
+  static oop class_loader(oop java_class);
+
   static int oop_size(oop java_class);
   static void set_oop_size(oop java_class, int size);
   static int static_oop_field_count(oop java_class);
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri Jun 20 12:45:24 2014 -0700
@@ -572,6 +572,7 @@
   template(serializePropertiesToByteArray_signature,   "()[B")                                                    \
   template(serializeAgentPropertiesToByteArray_name,   "serializeAgentPropertiesToByteArray")                     \
   template(classRedefinedCount_name,                   "classRedefinedCount")                                     \
+  template(classLoader_name,                           "classLoader")                                             \
                                                                                                                   \
   /* trace signatures */                                                                                          \
   TRACE_TEMPLATES(template)                                                                                       \
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -93,7 +93,7 @@
   ResourceMark rm(THREAD);
   k->initialize_supers(super_klass(), CHECK);
   k->vtable()->initialize_vtable(false, CHECK);
-  java_lang_Class::create_mirror(k, Handle(NULL), CHECK);
+  java_lang_Class::create_mirror(k, Handle(NULL), Handle(NULL), CHECK);
 }
 
 GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -71,7 +71,6 @@
 
   // only set to non-zero if constant pool is merged by RedefineClasses
   set_version(0);
-  set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock"));
 
   // initialize tag array
   int length = tags->length();
@@ -100,9 +99,6 @@
 void ConstantPool::release_C_heap_structures() {
   // walk constant pool and decrement symbol reference counts
   unreference_symbols();
-
-  delete _lock;
-  set_lock(NULL);
 }
 
 objArrayOop ConstantPool::resolved_references() const {
@@ -146,8 +142,7 @@
 // CDS support. Create a new resolved_references array.
 void ConstantPool::restore_unshareable_info(TRAPS) {
 
-  // Only create the new resolved references array and lock if it hasn't been
-  // attempted before
+  // Only create the new resolved references array if it hasn't been attempted before
   if (resolved_references() != NULL) return;
 
   // restore the C++ vtable from the shared archive
@@ -163,9 +158,6 @@
       ClassLoaderData* loader_data = pool_holder()->class_loader_data();
       set_resolved_references(loader_data->add_handle(refs_handle));
     }
-
-    // Also need to recreate the mutex.  Make sure this matches the constructor
-    set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock"));
   }
 }
 
@@ -176,7 +168,6 @@
   set_resolved_reference_length(
     resolved_references() != NULL ? resolved_references()->length() : 0);
   set_resolved_references(NULL);
-  set_lock(NULL);
 }
 
 int ConstantPool::cp_to_object_index(int cp_index) {
@@ -186,11 +177,41 @@
   return (i < 0) ? _no_index_sentinel : i;
 }
 
+void ConstantPool::trace_class_resolution(constantPoolHandle this_cp, KlassHandle k) {
+  ResourceMark rm;
+  int line_number = -1;
+  const char * source_file = NULL;
+  if (JavaThread::current()->has_last_Java_frame()) {
+    // try to identify the method which called this function.
+    vframeStream vfst(JavaThread::current());
+    if (!vfst.at_end()) {
+      line_number = vfst.method()->line_number_from_bci(vfst.bci());
+      Symbol* s = vfst.method()->method_holder()->source_file_name();
+      if (s != NULL) {
+        source_file = s->as_C_string();
+      }
+    }
+  }
+  if (k() != this_cp->pool_holder()) {
+    // only print something if the classes are different
+    if (source_file != NULL) {
+      tty->print("RESOLVE %s %s %s:%d\n",
+                 this_cp->pool_holder()->external_name(),
+                 InstanceKlass::cast(k())->external_name(), source_file, line_number);
+    } else {
+      tty->print("RESOLVE %s %s\n",
+                 this_cp->pool_holder()->external_name(),
+                 InstanceKlass::cast(k())->external_name());
+    }
+  }
+}
+
 Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) {
+  assert(THREAD->is_Java_thread(), "must be a Java thread");
+
   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
-  // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
-  // tag is not updated atomicly.
-
+  // It is not safe to rely on the tag bit's here, since we don't have a lock, and
+  // the entry and tag is not updated atomicly.
   CPSlot entry = this_cp->slot_at(which);
   if (entry.is_resolved()) {
     assert(entry.get_klass()->is_klass(), "must be");
@@ -198,115 +219,51 @@
     return entry.get_klass();
   }
 
-  // Acquire lock on constant oop while doing update. After we get the lock, we check if another object
-  // already has updated the object
-  assert(THREAD->is_Java_thread(), "must be a Java thread");
-  bool do_resolve = false;
-  bool in_error = false;
-
-  // Create a handle for the mirror. This will preserve the resolved class
-  // until the loader_data is registered.
-  Handle mirror_handle;
-
-  Symbol* name = NULL;
-  Handle       loader;
-  {  MonitorLockerEx ml(this_cp->lock());
-
-    if (this_cp->tag_at(which).is_unresolved_klass()) {
-      if (this_cp->tag_at(which).is_unresolved_klass_in_error()) {
-        in_error = true;
-      } else {
-        do_resolve = true;
-        name   = this_cp->unresolved_klass_at(which);
-        loader = Handle(THREAD, this_cp->pool_holder()->class_loader());
-      }
-    }
-  } // unlocking constantPool
-
-
-  // The original attempt to resolve this constant pool entry failed so find the
-  // class of the original error and throw another error of the same class (JVMS 5.4.3).
-  // If there is a detail message, pass that detail message to the error constructor.
-  // The JVMS does not strictly require us to duplicate the same detail message,
-  // or any internal exception fields such as cause or stacktrace.  But since the
-  // detail message is often a class name or other literal string, we will repeat it if
-  // we can find it in the symbol table.
-  if (in_error) {
+  // This tag doesn't change back to unresolved class unless at a safepoint.
+  if (this_cp->tag_at(which).is_unresolved_klass_in_error()) {
+    // The original attempt to resolve this constant pool entry failed so find the
+    // class of the original error and throw another error of the same class
+    // (JVMS 5.4.3).
+    // If there is a detail message, pass that detail message to the error.
+    // The JVMS does not strictly require us to duplicate the same detail message,
+    // or any internal exception fields such as cause or stacktrace.  But since the
+    // detail message is often a class name or other literal string, we will repeat it
+    // if we can find it in the symbol table.
     throw_resolution_error(this_cp, which, CHECK_0);
+    ShouldNotReachHere();
   }
 
-  if (do_resolve) {
-    // this_cp must be unlocked during resolve_or_fail
-    oop protection_domain = this_cp->pool_holder()->protection_domain();
-    Handle h_prot (THREAD, protection_domain);
-    Klass* kk = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);
-    KlassHandle k;
-    if (!HAS_PENDING_EXCEPTION) {
-      k = KlassHandle(THREAD, kk);
-      // preserve the resolved klass.
-      mirror_handle = Handle(THREAD, kk->java_mirror());
-      // Do access check for klasses
-      verify_constant_pool_resolve(this_cp, k, THREAD);
-    }
-
-    // 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) {
-        MonitorLockerEx ml(this_cp->lock());
-
-        // some other thread has beaten us and has resolved the class.
-        if (this_cp->tag_at(which).is_klass()) {
-          CLEAR_PENDING_EXCEPTION;
-          entry = this_cp->resolved_klass_at(which);
-          return entry.get_klass();
-        }
+  Handle mirror_handle;
+  Symbol* name = entry.get_symbol();
+  Handle loader (THREAD, this_cp->pool_holder()->class_loader());
+  Handle protection_domain (THREAD, this_cp->pool_holder()->protection_domain());
+  Klass* kk = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD);
+  KlassHandle k (THREAD, kk);
+  if (!HAS_PENDING_EXCEPTION) {
+    // preserve the resolved klass from unloading
+    mirror_handle = Handle(THREAD, kk->java_mirror());
+    // Do access check for klasses
+    verify_constant_pool_resolve(this_cp, k, THREAD);
+  }
 
-        // The tag could have changed to in-error before the lock but we have to
-        // handle that here for the class case.
-        save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0);
-    }
+  // 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) {
+    save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0);
+  }
 
-    if (TraceClassResolution && !k()->oop_is_array()) {
-      // skip resolving the constant pool so that this code get's
-      // called the next time some bytecodes refer to this class.
-      ResourceMark rm;
-      int line_number = -1;
-      const char * source_file = NULL;
-      if (JavaThread::current()->has_last_Java_frame()) {
-        // try to identify the method which called this function.
-        vframeStream vfst(JavaThread::current());
-        if (!vfst.at_end()) {
-          line_number = vfst.method()->line_number_from_bci(vfst.bci());
-          Symbol* s = vfst.method()->method_holder()->source_file_name();
-          if (s != NULL) {
-            source_file = s->as_C_string();
-          }
-        }
-      }
-      if (k() != this_cp->pool_holder()) {
-        // only print something if the classes are different
-        if (source_file != NULL) {
-          tty->print("RESOLVE %s %s %s:%d\n",
-                     this_cp->pool_holder()->external_name(),
-                     InstanceKlass::cast(k())->external_name(), source_file, line_number);
-        } else {
-          tty->print("RESOLVE %s %s\n",
-                     this_cp->pool_holder()->external_name(),
-                     InstanceKlass::cast(k())->external_name());
-        }
-      }
+  // Make this class loader depend upon the class loader owning the class reference
+  ClassLoaderData* this_key = this_cp->pool_holder()->class_loader_data();
+  this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
+
+  if (TraceClassResolution && !k->oop_is_array()) {
+    // skip resolving the constant pool so that this code gets
+    // called the next time some bytecodes refer to this class.
+    trace_class_resolution(this_cp, k);
       return k();
     } else {
-      MonitorLockerEx ml(this_cp->lock());
-      // Only updated constant pool - if it is resolved.
-      do_resolve = this_cp->tag_at(which).is_unresolved_klass();
-      if (do_resolve) {
-        ClassLoaderData* this_key = this_cp->pool_holder()->class_loader_data();
-        this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
         this_cp->klass_at_put(which, k());
       }
-    }
-  }
 
   entry = this_cp->resolved_klass_at(which);
   assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
@@ -576,7 +533,7 @@
   switch (tag.value()) {
   case JVM_CONSTANT_UnresolvedClass:
     // return the class name in the error message
-    message = this_cp->unresolved_klass_at(which);
+    message = this_cp->klass_name_at(which);
     break;
   case JVM_CONSTANT_MethodHandle:
     // return the method handle name in the error message
@@ -606,7 +563,6 @@
 // in the resolution error table, so that the same exception is thrown again.
 void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int which,
                                             constantTag tag, TRAPS) {
-  assert(this_cp->lock()->is_locked(), "constant pool lock should be held");
   Symbol* error = PENDING_EXCEPTION->klass()->name();
 
   int error_tag = tag.error_value();
@@ -620,7 +576,14 @@
   } else if (this_cp->tag_at(which).value() != error_tag) {
     Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION);
     SystemDictionary::add_resolution_error(this_cp, which, error, message);
-    this_cp->tag_at_put(which, error_tag);
+    // CAS in the tag.  If a thread beat us to registering this error that's fine.
+    // If another thread resolved the reference, this is an error.  The resolution
+    // must deterministically get an error.   So why do we save this?
+    // We save this because jvmti can add classes to the bootclass path after this
+    // error, so it needs to get the same error if the error is first.
+    jbyte old_tag = Atomic::cmpxchg((jbyte)error_tag,
+                            (jbyte*)this_cp->tag_addr_at(which), (jbyte)tag.value());
+    assert(old_tag == error_tag || old_tag == tag.value(), "should not be resolved otherwise");
   } else {
     // some other thread put this in error state
     throw_resolution_error(this_cp, which, CHECK);
@@ -710,7 +673,6 @@
                                                                    THREAD);
       result_oop = value();
       if (HAS_PENDING_EXCEPTION) {
-        MonitorLockerEx ml(this_cp->lock());  // lock cpool to change tag.
         save_and_throw_exception(this_cp, index, tag, CHECK_NULL);
       }
       break;
@@ -727,7 +689,6 @@
       Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
       result_oop = value();
       if (HAS_PENDING_EXCEPTION) {
-        MonitorLockerEx ml(this_cp->lock());  // lock cpool to change tag.
         save_and_throw_exception(this_cp, index, tag, CHECK_NULL);
       }
       break;
@@ -765,22 +726,17 @@
   }
 
   if (cache_index >= 0) {
-    // Cache the oop here also.
-    Handle result_handle(THREAD, result_oop);
-    MonitorLockerEx ml(this_cp->lock());  // don't know if we really need this
-    oop result = this_cp->resolved_references()->obj_at(cache_index);
-    // Benign race condition:  resolved_references may already be filled in while we were trying to lock.
+    // Benign race condition:  resolved_references may already be filled in.
     // The important thing here is that all threads pick up the same result.
     // It doesn't matter which racing thread wins, as long as only one
     // result is used by all threads, and all future queries.
-    // That result may be either a resolved constant or a failure exception.
-    if (result == NULL) {
-      this_cp->resolved_references()->obj_at_put(cache_index, result_handle());
-      return result_handle();
+    oop old_result = this_cp->resolved_references()->atomic_compare_exchange_oop(cache_index, result_oop, NULL);
+    if (old_result == NULL) {
+      return result_oop;  // was installed
     } else {
       // Return the winning thread's result.  This can be different than
-      // result_handle() for MethodHandles.
-      return result;
+      // the result here for MethodHandles.
+      return old_result;
     }
   } else {
     return result_oop;
@@ -853,9 +809,8 @@
 }
 
 
-// Iterate over symbols and decrement ones which are Symbol*s.
-// This is done during GC so do not need to lock constantPool unless we
-// have per-thread safepoints.
+// Iterate over symbols and decrement ones which are Symbol*s
+// This is done during GC.
 // Only decrement the UTF8 symbols. Unresolved classes and strings point to
 // these symbols but didn't increment the reference count.
 void ConstantPool::unreference_symbols() {
@@ -987,8 +942,8 @@
 
   case JVM_CONSTANT_UnresolvedClass:
   {
-    Symbol* k1 = unresolved_klass_at(index1);
-    Symbol* k2 = cp2->unresolved_klass_at(index2);
+    Symbol* k1 = klass_name_at(index1);
+    Symbol* k2 = cp2->klass_name_at(index2);
     if (k1 == k2) {
       return true;
     }
@@ -1970,7 +1925,6 @@
       break;
     case JVM_CONSTANT_UnresolvedClass :               // fall-through
     case JVM_CONSTANT_UnresolvedClassInError: {
-      // unresolved_klass_at requires lock or safe world.
       CPSlot entry = slot_at(index);
       if (entry.is_resolved()) {
         entry.get_klass()->print_value_on(st);
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Fri Jun 20 12:45:24 2014 -0700
@@ -112,12 +112,12 @@
     int                _version;
   } _saved;
 
-  Monitor*             _lock;
-
   void set_tags(Array<u1>* tags)               { _tags = tags; }
   void tag_at_put(int which, jbyte t)          { tags()->at_put(which, t); }
   void release_tag_at_put(int which, jbyte t)  { tags()->release_at_put(which, t); }
 
+  u1* tag_addr_at(int which) const             { return tags()->adr_at(which); }
+
   void set_operands(Array<u2>* operands)       { _operands = operands; }
 
   int flags() const                            { return _flags; }
@@ -362,14 +362,6 @@
     return CPSlot((Klass*)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_klass();
   }
 
-  // This method should only be used with a cpool lock or during parsing or gc
-  Symbol* unresolved_klass_at(int which) {     // Temporary until actual use
-    Symbol* s = CPSlot((Symbol*)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_symbol();
-    // check that the klass is still unresolved.
-    assert(tag_at(which).is_unresolved_klass(), "Corrupted constant pool");
-    return s;
-  }
-
   // RedefineClasses() API support:
   Symbol* klass_at_noresolve(int which) { return klass_name_at(which); }
 
@@ -818,6 +810,8 @@
   static Klass* klass_at_impl(constantPoolHandle this_cp, int which, TRAPS);
   static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS);
 
+  static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k);
+
   // Resolve string constants (to prevent allocation during compilation)
   static void resolve_string_constants_impl(constantPoolHandle this_cp, TRAPS);
 
@@ -848,8 +842,6 @@
 
   void set_resolved_reference_length(int length) { _saved._resolved_reference_length = length; }
   int  resolved_reference_length() const  { return _saved._resolved_reference_length; }
-  void set_lock(Monitor* lock)            { _lock = lock; }
-  Monitor* lock()                         { return _lock; }
 
   // Decrease ref counts of symbols that are in the constant pool
   // when the holder class is unloaded
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -286,7 +286,9 @@
   // the lock, so that when the losing writer returns, he can use the linked
   // cache entry.
 
-  MonitorLockerEx ml(cpool->lock());
+  // Use the lock from the metaspace for this, which cannot stop for safepoint.
+  Mutex* metaspace_lock = cpool->pool_holder()->class_loader_data()->metaspace_lock();
+  MutexLockerEx ml(metaspace_lock,  Mutex::_no_safepoint_check_flag);
   if (!is_f1_null()) {
     return;
   }
--- a/hotspot/src/share/vm/oops/klass.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -508,7 +508,7 @@
   // Only recreate it if not present.  A previous attempt to restore may have
   // gotten an OOM later but keep the mirror if it was created.
   if (java_mirror() == NULL) {
-    java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
+    java_lang_Class::create_mirror(this, Handle(NULL), Handle(NULL), CHECK);
   }
 }
 
--- a/hotspot/src/share/vm/oops/objArrayOop.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/objArrayOop.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,22 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 
+oop objArrayOopDesc::atomic_compare_exchange_oop(int index, oop exchange_value,
+                                                 oop compare_value) {
+  volatile HeapWord* dest;
+  if (UseCompressedOops) {
+    dest = (HeapWord*)obj_at_addr<narrowOop>(index);
+  } else {
+    dest = (HeapWord*)obj_at_addr<oop>(index);
+  }
+  oop res = oopDesc::atomic_compare_exchange_oop(exchange_value, dest, compare_value, true);
+  // update card mark if success
+  if (res == compare_value) {
+    update_barrier_set((void*)dest, exchange_value);
+  }
+  return res;
+}
+
 #define ObjArrayOop_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                    \
                                                                                    \
 int objArrayOopDesc::oop_iterate_range(OopClosureType* blk, int start, int end) {  \
--- a/hotspot/src/share/vm/oops/objArrayOop.hpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/oops/objArrayOop.hpp	Fri Jun 20 12:45:24 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,6 +95,9 @@
       oop_store(obj_at_addr<oop>(index), value);
     }
   }
+
+  oop atomic_compare_exchange_oop(int index, oop exchange_value, oop compare_value);
+
   // Sizing
   static int header_size()    { return arrayOopDesc::header_size(T_OBJECT); }
   int object_size()           { return object_size(length()); }
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -258,9 +258,6 @@
       // VM representation. We don't attach the reconstituted class
       // bytes to the InstanceKlass here because they have not been
       // validated and we're not at a safepoint.
-      constantPoolHandle  constants(current_thread, ikh->constants());
-      MonitorLockerEx ml(constants->lock());    // lock constant pool while we query it
-
       JvmtiClassFileReconstituter reconstituter(ikh);
       if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
         return reconstituter.get_error();
@@ -2445,9 +2442,6 @@
   }
 
   instanceKlassHandle ikh(thread, k_oop);
-  constantPoolHandle  constants(thread, ikh->constants());
-  MonitorLockerEx ml(constants->lock());    // lock constant pool while we query it
-
   JvmtiConstantPoolReconstituter reconstituter(ikh);
   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
     return reconstituter.get_error();
@@ -2467,6 +2461,7 @@
     return reconstituter.get_error();
   }
 
+  constantPoolHandle  constants(thread, ikh->constants());
   *constant_pool_count_ptr      = constants->length();
   *constant_pool_byte_count_ptr = cpool_size;
   *constant_pool_bytes_ptr      = cpool_bytes;
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Fri Jun 20 11:10:18 2014 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Fri Jun 20 12:45:24 2014 -0700
@@ -891,6 +891,14 @@
   }
 UNSAFE_END
 
+static jobject get_class_loader(JNIEnv* env, jclass cls) {
+  if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
+    return NULL;
+  }
+  Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
+  oop loader = k->class_loader();
+  return JNIHandles::make_local(env, loader);
+}
 
 UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length))
   UnsafeWrapper("Unsafe_DefineClass");
@@ -899,7 +907,7 @@
 
     int depthFromDefineClass0 = 1;
     jclass  caller = JVM_GetCallerClass(env, depthFromDefineClass0);
-    jobject loader = (caller == NULL) ? NULL : JVM_GetClassLoader(env, caller);
+    jobject loader = (caller == NULL) ? NULL : get_class_loader(env, caller);
     jobject pd     = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller);
 
     return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/verifier/TestANewArray.java	Fri Jun 20 12:45:24 2014 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+import com.oracle.java.testlibrary.*;
+
+/*
+ * @test
+ * @summary Test that anewarray bytecode is valid only if it specifies 255 or fewer dimensions.
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestANewArray.java
+ * @run main/othervm TestANewArray 49
+ * @run main/othervm TestANewArray 50
+ * @run main/othervm TestANewArray 51
+ * @run main/othervm TestANewArray 52
+ */
+
+/*
+ * Testing anewarray instruction with 254, 255 & 264 dimensions to verify JVMS 8,
+ * Section 4.9.1, Static Constraints that states the following:
+ *
+ * "No anewarray instruction may be used to create an array of more than 255 dimensions."
+ *
+ */
+
+public class TestANewArray {
+
+    static String classCName = null; // the generated class name
+
+    static final int test_Dimension_254 = 254; // should always pass
+    static final int test_Dimension_255 = 255; // should always pass, except for cfv 49
+    static final int test_Dimension_264 = 264; // should always fail
+
+    static final String array_Dimension_254 = genArrayDim(test_Dimension_254);
+    static final String array_Dimension_255 = genArrayDim(test_Dimension_255);
+    static final String array_Dimension_264 = genArrayDim(test_Dimension_264);
+
+    public static void main(String... args) throws Exception {
+        int cfv = Integer.parseInt(args[0]);
+
+        // 254 array dimensions
+        byte[] classFile_254 = dumpClassFile(cfv, test_Dimension_254, array_Dimension_254);
+        writeClassFileFromByteArray(classFile_254);
+        System.err.println("Running with cfv: " + cfv + ", test_Dimension_254");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".",  classCName);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("java.lang.VerifyError");
+        output.shouldHaveExitValue(0);
+
+        // 255 array dimensions
+        byte[] classFile_255 = dumpClassFile(cfv, test_Dimension_255, array_Dimension_255);
+        writeClassFileFromByteArray(classFile_255);
+        System.err.println("Running with cfv: " + cfv + ", test_Dimension_255");
+        pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".",  classCName);
+        output = new OutputAnalyzer(pb.start());
+        if (cfv == 49) {
+            // The type-inferencing verifier used for <=49.0 ClassFiles detects an anewarray instruction
+            // with exactly 255 dimensions and incorrectly issues the "Array with too many dimensions" VerifyError.
+            output.shouldContain("Array with too many dimensions");
+            output.shouldHaveExitValue(1);
+        } else {
+            // 255 dimensions should always pass, except for cfv 49
+            output.shouldNotContain("java.lang.VerifyError");
+            output.shouldNotContain("java.lang.ClassFormatError");
+            output.shouldHaveExitValue(0);
+        }
+
+        // 264 array dimensions
+        byte[] classFile_264 = dumpClassFile(cfv, test_Dimension_264, array_Dimension_264);
+        writeClassFileFromByteArray(classFile_264);
+        System.err.println("Running with cfv: " + cfv + ", test_Dimension_264");
+        pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".",  classCName);
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("java.lang.ClassFormatError");
+        output.shouldHaveExitValue(1);
+    }
+
+    public static byte[] dumpClassFile(int cfv, int testDimension264, String arrayDim) throws Exception {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+        MethodVisitor mv;
+
+        classCName = "classCName_" + cfv + "_" + testDimension264;
+
+        cw.visit(cfv, ACC_PUBLIC + ACC_SUPER, classCName, null, "java/lang/Object", null);
+        {
+            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(1, 1);
+            mv.visitEnd();
+        }
+        {   // classCName main method
+            mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+            mv.visitCode();
+            mv.visitIntInsn(BIPUSH, 1);
+            mv.visitTypeInsn(ANEWARRAY, arrayDim); // Test ANEWARRAY bytecode with various dimensions
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(2, 2);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    public static FileOutputStream writeClassFileFromByteArray(byte[] classFileByteArray) throws Exception {
+        FileOutputStream fos = new FileOutputStream(new File(classCName + ".class"));
+        fos.write(classFileByteArray);
+        fos.close();
+        return fos;
+    }
+
+    private static String genArrayDim(int testDim) {
+        StringBuilder array_Dimension = new StringBuilder();
+        for (int i = 0; i < testDim; i++)
+        {
+            array_Dimension.append("[");
+        }
+        return array_Dimension.append("Ljava/lang/Object;").toString();
+    }
+}