changeset 3139:aa67216400d3

7085404: JSR 292: VolatileCallSites should have push notification too Reviewed-by: never, kvn
author twisti
date Fri, 02 Sep 2011 00:36:18 -0700
parents a32de5085326
children 11a4af030e4b
files src/share/vm/c1/c1_GraphBuilder.cpp src/share/vm/ci/ciField.hpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/opto/callGenerator.cpp src/share/vm/opto/doCall.cpp src/share/vm/opto/parse3.cpp src/share/vm/prims/unsafe.cpp
diffstat 7 files changed, 36 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Sep 02 00:36:18 2011 -0700
@@ -3744,26 +3744,20 @@
   ciCallSite*     call_site     = stream()->get_call_site();
   ciMethodHandle* method_handle = call_site->get_target();
 
-  // Inline constant and mutable call sites.  We don't inline
-  // volatile call sites optimistically since they are specified
-  // to change their value often and that would result in a lot of
-  // deoptimizations and recompiles.
-  if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) {
-    // Set the callee to have access to the class and signature in the
-    // MethodHandleCompiler.
-    method_handle->set_callee(callee);
-    method_handle->set_caller(method());
-
-    // Get an adapter for the MethodHandle.
-    ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter();
-    if (method_handle_adapter != NULL) {
-      if (try_inline(method_handle_adapter, /*holder_known=*/ true)) {
-        // Add a dependence for invalidation of the optimization.
-        if (!call_site->is_constant_call_site()) {
-          dependency_recorder()->assert_call_site_target_value(call_site, method_handle);
-        }
-        return true;
+  // Set the callee to have access to the class and signature in the
+  // MethodHandleCompiler.
+  method_handle->set_callee(callee);
+  method_handle->set_caller(method());
+
+  // Get an adapter for the MethodHandle.
+  ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter();
+  if (method_handle_adapter != NULL) {
+    if (try_inline(method_handle_adapter, /*holder_known=*/ true)) {
+      // Add a dependence for invalidation of the optimization.
+      if (!call_site->is_constant_call_site()) {
+        dependency_recorder()->assert_call_site_target_value(call_site, method_handle);
       }
+      return true;
     }
   }
   return false;
--- a/src/share/vm/ci/ciField.hpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/ci/ciField.hpp	Fri Sep 02 00:36:18 2011 -0700
@@ -175,7 +175,9 @@
   bool is_volatile    () { return flags().is_volatile(); }
   bool is_transient   () { return flags().is_transient(); }
 
-  bool is_call_site_target() { return ((holder() == CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name())); }
+  bool is_call_site_target() {
+    return (holder()->is_subclass_of(CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name()));
+  }
 
   // Debugging output
   void print();
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 02 00:36:18 2011 -0700
@@ -555,7 +555,7 @@
     assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
 
     {
-      // Walk all nmethods depending on CallSite
+      // Walk all nmethods depending on this call site.
       MutexLocker mu(Compile_lock, thread);
       Universe::flush_dependents_on(call_site, method_handle);
     }
--- a/src/share/vm/opto/callGenerator.cpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/opto/callGenerator.cpp	Fri Sep 02 00:36:18 2011 -0700
@@ -726,7 +726,6 @@
 
 CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms,
                                                        ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
-  assert(call_site->is_constant_call_site() || call_site->is_mutable_call_site(), "must be");
   ciMethodHandle* method_handle = call_site->get_target();
 
   // Set the callee to have access to the class and signature in the
@@ -742,7 +741,7 @@
     CallGenerator* cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
     if (cg != NULL && cg->is_inline()) {
       // Add a dependence for invalidation of the optimization.
-      if (call_site->is_mutable_call_site()) {
+      if (!call_site->is_constant_call_site()) {
         C->dependencies()->assert_call_site_target_value(call_site, method_handle);
       }
       return cg;
--- a/src/share/vm/opto/doCall.cpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/opto/doCall.cpp	Fri Sep 02 00:36:18 2011 -0700
@@ -136,15 +136,9 @@
       str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
       ciCallSite* call_site = str.get_call_site();
 
-      // Inline constant and mutable call sites.  We don't inline
-      // volatile call sites optimistically since they are specified
-      // to change their value often and that would result in a lot of
-      // deoptimizations and recompiles.
-      if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) {
-        CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile);
-        if (cg != NULL) {
-          return cg;
-        }
+      CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile);
+      if (cg != NULL) {
+        return cg;
       }
       // If something failed, generate a normal dynamic call.
       return CallGenerator::for_dynamic_call(call_method);
--- a/src/share/vm/opto/parse3.cpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/opto/parse3.cpp	Fri Sep 02 00:36:18 2011 -0700
@@ -100,11 +100,11 @@
     }
   }
 
-  // Deoptimize on putfield writes to CallSite.target
+  // Deoptimize on putfield writes to call site target field.
   if (!is_get && field->is_call_site_target()) {
     uncommon_trap(Deoptimization::Reason_unhandled,
                   Deoptimization::Action_reinterpret,
-                  NULL, "put to CallSite.target field");
+                  NULL, "put to call site target field");
     return;
   }
 
--- a/src/share/vm/prims/unsafe.cpp	Thu Sep 01 01:31:25 2011 -0700
+++ b/src/share/vm/prims/unsafe.cpp	Fri Sep 02 00:36:18 2011 -0700
@@ -302,6 +302,19 @@
   UnsafeWrapper("Unsafe_SetObjectVolatile");
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
+  // Catch VolatileCallSite.target stores (via
+  // CallSite.setTargetVolatile) and check call site dependencies.
+  if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) {
+    oop call_site     = p;
+    oop method_handle = x;
+    assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "must be");
+    assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
+    {
+      // Walk all nmethods depending on this call site.
+      MutexLocker mu(Compile_lock, thread);
+      Universe::flush_dependents_on(call_site, method_handle);
+    }
+  }
   void* addr = index_oop_from_field_offset_long(p, offset);
   OrderAccess::release();
   if (UseCompressedOops) {