diff src/share/vm/interpreter/interpreterRuntime.cpp @ 3852:fdb992d83a87

7071653: JSR 292: call site change notification should be pushed not pulled Reviewed-by: kvn, never, bdelsart
author twisti
date Tue, 16 Aug 2011 04:14:05 -0700
parents 2c359f27615c
children aa67216400d3 2fecca53a2c6
line wrap: on
line diff
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Aug 11 12:08:11 2011 -0700
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Aug 16 04:14:05 2011 -0700
@@ -509,6 +509,7 @@
   // resolve field
   FieldAccessInfo info;
   constantPoolHandle pool(thread, method(thread)->constants());
+  bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_putstatic);
   bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
 
   {
@@ -528,8 +529,6 @@
   // exceptions at the correct place. If we do not resolve completely
   // in the current pass, leaving the put_code set to zero will
   // cause the next put instruction to reresolve.
-  bool is_put = (bytecode == Bytecodes::_putfield ||
-                 bytecode == Bytecodes::_putstatic);
   Bytecodes::Code put_code = (Bytecodes::Code)0;
 
   // We also need to delay resolving getstatic instructions until the
@@ -541,7 +540,6 @@
                                !klass->is_initialized());
   Bytecodes::Code get_code = (Bytecodes::Code)0;
 
-
   if (!uninitialized_static) {
     get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
     if (is_put || !info.access_flags().is_final()) {
@@ -549,6 +547,23 @@
     }
   }
 
+  if (is_put && !is_static && klass->is_subclass_of(SystemDictionary::CallSite_klass()) && (info.name() == vmSymbols::target_name())) {
+    const jint direction = frame::interpreter_frame_expression_stack_direction();
+    oop call_site     = *((oop*) thread->last_frame().interpreter_frame_tos_at(-1 * direction));
+    oop method_handle = *((oop*) thread->last_frame().interpreter_frame_tos_at( 0 * direction));
+    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 CallSite
+      MutexLocker mu(Compile_lock, thread);
+      Universe::flush_dependents_on(call_site, method_handle);
+    }
+
+    // Don't allow fast path for setting CallSite.target and sub-classes.
+    put_code = (Bytecodes::Code) 0;
+  }
+
   cache_entry(thread)->set_field(
     get_code,
     put_code,