changeset 3613:4bfe8b33cf66

7196242: vm/mlvm/indy/stress/java/loopsAndThreads crashed Reviewed-by: jrose, coleenp, jmasa, kvn
author twisti
date Mon, 10 Sep 2012 16:37:22 -0700
parents 11fb740ce98f
children ec98e58952b2
files src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/oops/cpCache.cpp src/share/vm/oops/cpCache.hpp
diffstat 3 files changed, 23 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 07 16:42:25 2012 -0400
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Sep 10 16:37:22 2012 -0700
@@ -734,6 +734,7 @@
   } // end JvmtiHideSingleStepping
 
   cache_entry(thread)->set_method_handle(
+      pool,
       info.resolved_method(),
       info.resolved_appendix(),
       pool->resolved_references());
@@ -761,6 +762,7 @@
 
   ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index);
   cp_cache_entry->set_dynamic_call(
+      pool,
       info.resolved_method(),
       info.resolved_appendix(),
       pool->resolved_references());
--- a/src/share/vm/oops/cpCache.cpp	Fri Sep 07 16:42:25 2012 -0400
+++ b/src/share/vm/oops/cpCache.cpp	Mon Sep 10 16:37:22 2012 -0700
@@ -243,17 +243,20 @@
 }
 
 
-void ConstantPoolCacheEntry::set_method_handle(methodHandle adapter, Handle appendix,
+void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
+                                               methodHandle adapter, Handle appendix,
                                                objArrayHandle resolved_references) {
-  set_method_handle_common(Bytecodes::_invokehandle, adapter, appendix, resolved_references);
+  set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, resolved_references);
 }
 
-void ConstantPoolCacheEntry::set_dynamic_call(methodHandle adapter, Handle appendix,
+void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
+                                              methodHandle adapter, Handle appendix,
                                               objArrayHandle resolved_references) {
-  set_method_handle_common(Bytecodes::_invokedynamic, adapter, appendix, resolved_references);
+  set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, resolved_references);
 }
 
-void ConstantPoolCacheEntry::set_method_handle_common(Bytecodes::Code invoke_code,
+void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
+                                                      Bytecodes::Code invoke_code,
                                                       methodHandle adapter,
                                                       Handle appendix,
                                                       objArrayHandle resolved_references) {
@@ -261,28 +264,23 @@
   // There are three words to update: flags, refs[f2], f1 (in that order).
   // Writers must store all other values before f1.
   // Readers must test f1 first for non-null before reading other fields.
-  // Competing writers must acquire exclusive access on the first
-  // write, to flags, using a compare/exchange.
-  // A losing writer to flags must spin until the winner writes f1,
-  // so that when he returns, he can use the linked cache entry.
+  // Competing writers must acquire exclusive access via a lock.
+  // A losing writer waits on the lock until the winner writes f1 and leaves
+  // the lock, so that when the losing writer returns, he can use the linked
+  // cache entry.
+
+  MonitorLockerEx ml(cpool->lock());
+  if (!is_f1_null()) {
+    return;
+  }
 
   bool has_appendix = appendix.not_null();
 
   // Write the flags.
-  bool owner =
-    init_method_flags_atomic(as_TosState(adapter->result_type()),
+  set_method_flags(as_TosState(adapter->result_type()),
                    ((has_appendix ?  1 : 0) << has_appendix_shift) |
                    (                 1      << is_final_shift),
                    adapter->size_of_parameters());
-  if (!owner) {
-    // Somebody else is working on the same CPCE.  Let them proceed.
-    while (is_f1_null()) {
-      // Pause momentarily on a low-level lock, to allow racing thread to win.
-      MutexLockerEx mu(Patching_lock, Mutex::_no_safepoint_check_flag);
-      os::yield();
-    }
-    return;
-  }
 
   if (TraceInvokeDynamic) {
     tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ",
--- a/src/share/vm/oops/cpCache.hpp	Fri Sep 07 16:42:25 2012 -0400
+++ b/src/share/vm/oops/cpCache.hpp	Mon Sep 10 16:37:22 2012 -0700
@@ -221,12 +221,14 @@
   );
 
   void set_method_handle(
+    constantPoolHandle cpool,                    // holding constant pool (required for locking)
     methodHandle method,                         // adapter for invokeExact, etc.
     Handle appendix,                             // stored in refs[f2]; could be a java.lang.invoke.MethodType
     objArrayHandle resolved_references
   );
 
   void set_dynamic_call(
+    constantPoolHandle cpool,                    // holding constant pool (required for locking)
     methodHandle method,                         // adapter for this call site
     Handle appendix,                             // stored in refs[f2]; could be a java.lang.invoke.CallSite
     objArrayHandle resolved_references
@@ -248,6 +250,7 @@
   // resolution logic needs to make slightly different assessments about the
   // number and types of arguments.
   void set_method_handle_common(
+    constantPoolHandle cpool,                    // holding constant pool (required for locking)
     Bytecodes::Code invoke_code,                 // _invokehandle or _invokedynamic
     methodHandle adapter,                        // invoker method (f1)
     Handle appendix,                             // appendix such as CallSite, MethodType, etc. (refs[f2])