6990192: VM crashes in ciTypeFlow::get_block_for()
authortwisti
Tue, 19 Oct 2010 02:52:57 -0700
changeset 7104 0c8b519af363
parent 7102 a20be5bfcbee
child 7105 849cbf3e4d6a
6990192: VM crashes in ciTypeFlow::get_block_for() Reviewed-by: never
hotspot/src/share/vm/classfile/systemDictionary.cpp
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
hotspot/src/share/vm/oops/cpCacheOop.cpp
hotspot/src/share/vm/oops/cpCacheOop.hpp
hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Mon Oct 18 01:54:24 2010 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Tue Oct 19 02:52:57 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -26,12 +26,12 @@
 # include "incls/_systemDictionary.cpp.incl"
 
 
-Dictionary*       SystemDictionary::_dictionary = NULL;
-PlaceholderTable* SystemDictionary::_placeholders = NULL;
-Dictionary*       SystemDictionary::_shared_dictionary = NULL;
-LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL;
-ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL;
-SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
+Dictionary*            SystemDictionary::_dictionary          = NULL;
+PlaceholderTable*      SystemDictionary::_placeholders        = NULL;
+Dictionary*            SystemDictionary::_shared_dictionary   = NULL;
+LoaderConstraintTable* SystemDictionary::_loader_constraints  = NULL;
+ResolutionErrorTable*  SystemDictionary::_resolution_errors   = NULL;
+SymbolPropertyTable*   SystemDictionary::_invoke_method_table = NULL;
 
 
 int         SystemDictionary::_number_of_modifications = 0;
@@ -1727,8 +1727,7 @@
   placeholders_do(blk);
 
   // Visit extra methods
-  if (invoke_method_table() != NULL)
-    invoke_method_table()->oops_do(blk);
+  invoke_method_table()->oops_do(blk);
 
   // Loader constraints. We must keep the symbolOop used in the name alive.
   constraints()->always_strong_classes_do(blk);
@@ -1766,8 +1765,7 @@
   dictionary()->oops_do(f);
 
   // Visit extra methods
-  if (invoke_method_table() != NULL)
-    invoke_method_table()->oops_do(f);
+  invoke_method_table()->oops_do(f);
 
   // Partially loaded classes
   placeholders()->oops_do(f);
@@ -1841,8 +1839,7 @@
 
 void SystemDictionary::methods_do(void f(methodOop)) {
   dictionary()->methods_do(f);
-  if (invoke_method_table() != NULL)
-    invoke_method_table()->methods_do(f);
+  invoke_method_table()->methods_do(f);
 }
 
 // ----------------------------------------------------------------------------
@@ -1870,12 +1867,12 @@
   // Allocate arrays
   assert(dictionary() == NULL,
          "SystemDictionary should only be initialized once");
-  _dictionary = new Dictionary(_nof_buckets);
-  _placeholders = new PlaceholderTable(_nof_buckets);
+  _dictionary          = new Dictionary(_nof_buckets);
+  _placeholders        = new PlaceholderTable(_nof_buckets);
   _number_of_modifications = 0;
-  _loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
-  _resolution_errors = new ResolutionErrorTable(_resolution_error_size);
-  // _invoke_method_table is allocated lazily in find_method_handle_invoke()
+  _loader_constraints  = new LoaderConstraintTable(_loader_constraint_size);
+  _resolution_errors   = new ResolutionErrorTable(_resolution_error_size);
+  _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
 
   // Allocate private object used as system class loader lock
   _system_loader_lock_obj = oopFactory::new_system_objArray(0, CHECK);
@@ -2346,10 +2343,6 @@
                                                       KlassHandle accessing_klass,
                                                       TRAPS) {
   if (!EnableMethodHandles)  return NULL;
-  if (invoke_method_table() == NULL) {
-    // create this side table lazily
-    _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
-  }
   vmSymbols::SID name_id = vmSymbols::find_sid(name());
   assert(name_id != vmSymbols::NO_SID, "must be a known name");
   unsigned int hash  = invoke_method_table()->compute_hash(signature, name_id);
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Oct 18 01:54:24 2010 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Oct 19 02:52:57 2010 -0700
@@ -720,8 +720,8 @@
   // first resolve the signature to a MH.invoke methodOop
   if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) {
     JvmtiHideSingleStepping jhss(thread);
-    CallInfo info;
-    LinkResolver::resolve_invoke(info, Handle(), pool,
+    CallInfo callinfo;
+    LinkResolver::resolve_invoke(callinfo, Handle(), pool,
                                  site_index, bytecode, CHECK);
     // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves
     // as a common reference point for all invokedynamic call sites with
@@ -729,8 +729,8 @@
     // as if it were an invokevirtual of MethodHandle.invoke.
     pool->cache()->entry_at(main_index)->set_method(
       bytecode,
-      info.resolved_method(),
-      info.vtable_index());
+      callinfo.resolved_method(),
+      callinfo.vtable_index());
   }
 
   // The method (f2 entry) of the main entry is the MH.invoke for the
--- a/hotspot/src/share/vm/oops/cpCacheOop.cpp	Mon Oct 18 01:54:24 2010 -0700
+++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp	Tue Oct 19 02:52:57 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -87,6 +87,19 @@
   OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << 24));
 }
 
+// Atomically sets f1 if it is still NULL, otherwise it keeps the
+// current value.
+void ConstantPoolCacheEntry::set_f1_if_null_atomic(oop f1) {
+    // Use barriers as in oop_store
+    HeapWord* f1_addr = (HeapWord*) &_f1;
+    update_barrier_set_pre(f1_addr, f1);
+    void* result = Atomic::cmpxchg_ptr(f1, f1_addr, NULL);
+    bool success = (result == NULL);
+    if (success) {
+      update_barrier_set((void*) f1_addr, f1);
+    }
+  }
+
 #ifdef ASSERT
 // It is possible to have two different dummy methodOops created
 // when the resolve code for invoke interface executes concurrently
@@ -165,7 +178,12 @@
       }
       assert(method->can_be_statically_bound(), "must be a MH invoker method");
       assert(AllowTransitionalJSR292 || _f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
-      set_f1(method());
+      // SystemDictionary::find_method_handle_invoke only caches
+      // methods which signature classes are on the boot classpath,
+      // otherwise the newly created method is returned.  To avoid
+      // races in that case we store the first one coming in into the
+      // cp-cache atomically if it's still unset.
+      set_f1_if_null_atomic(method());
       needs_vfinal_flag = false;  // _f2 is not an oop
       assert(!is_vfinal(), "f2 not an oop");
       byte_no = 1;  // coordinate this with bytecode_number & is_resolved
--- a/hotspot/src/share/vm/oops/cpCacheOop.hpp	Mon Oct 18 01:54:24 2010 -0700
+++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp	Tue Oct 19 02:52:57 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -130,6 +130,7 @@
     assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
     oop_store(&_f1, f1);
   }
+  void set_f1_if_null_atomic(oop f1);
   void set_f2(intx f2)                           { assert(_f2 == 0    || _f2 == f2, "illegal field change"); _f2 = f2; }
   int as_flags(TosState state, bool is_final, bool is_vfinal, bool is_volatile,
                bool is_method_interface, bool is_method);
--- a/hotspot/src/share/vm/runtime/thread.cpp	Mon Oct 18 01:54:24 2010 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Oct 19 02:52:57 2010 -0700
@@ -1199,6 +1199,7 @@
   _exception_pc  = 0;
   _exception_handler_pc = 0;
   _exception_stack_size = 0;
+  _is_method_handle_return = 0;
   _jvmti_thread_state= NULL;
   _should_post_on_exceptions_flag = JNI_FALSE;
   _jvmti_get_loaded_classes_closure = NULL;