< prev index next >

src/hotspot/share/runtime/javaCalls.cpp

Print this page

        

@@ -28,10 +28,13 @@
 #include "code/nmethod.hpp"
 #include "compiler/compilationPolicy.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/linkResolver.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciJavaClasses.hpp"
+#endif
 #include "memory/universe.hpp"
 #include "oops/method.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jniCheck.hpp"
 #include "runtime/handles.inline.hpp"

@@ -345,20 +348,18 @@
   assert(method.not_null(), "must have a method to call");
   assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");
   assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");
 
 #if INCLUDE_JVMCI
-  // Gets the nmethod (if any) that should be called instead of normal target
-  nmethod* alternative_target = args->alternative_target();
-  if (alternative_target == NULL) {
+  // Gets the alternative target (if any) that should be called
+  Handle alternative_target = args->alternative_target();
+  if (alternative_target.is_null()) {
 #endif
-// Verify the arguments
-
-  if (CheckJNICalls)  {
+    // Verify the arguments
+    if (DEBUG_ONLY(true ||) CheckJNICalls)  {
     args->verify(method, result->get_type());
   }
-  else debug_only(args->verify(method, result->get_type()));
 #if INCLUDE_JVMCI
   }
 #else
 
   // Ignore call if method is empty

@@ -412,30 +413,34 @@
   } else {
     // Touch pages checked if the OS needs them to be touched to be mapped.
     os::map_stack_shadow_pages(sp);
   }
 
-#if INCLUDE_JVMCI
-  if (alternative_target != NULL) {
-    if (alternative_target->is_alive() && !alternative_target->is_unloading()) {
-      thread->set_jvmci_alternate_call_target(alternative_target->verified_entry_point());
-      entry_point = method->adapter()->get_i2c_entry();
-    } else {
-      THROW(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException());
-    }
-  }
-#endif
-
   // do call
   { JavaCallWrapper link(method, receiver, result, CHECK);
     { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner
 
       // NOTE: if we move the computation of the result_val_address inside
       // the call to call_stub, the optimizer produces wrong code.
       intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
       intptr_t* parameter_address = args->parameters();
-
+#if INCLUDE_JVMCI
+      if (!alternative_target.is_null()) {
+        // Must extract verified entry point from HotSpotNmethod after VM to Java
+        // transition in JavaCallWrapper constructor so that it is safe with
+        // respect to nmethod sweeping.
+        address verified_entry_point = (address) HotSpotJVMCI::InstalledCode::entryPoint(NULL, alternative_target());
+        if (verified_entry_point != 0) {
+          thread->set_jvmci_alternate_call_target(verified_entry_point);
+          entry_point = method->adapter()->get_i2c_entry();
+        } else {
+          // Sweeper made nmethod non-entrant or zombie at VM to Java transition
+          entry_point = NULL;
+        }
+      }
+      if (entry_point != NULL) {
+#endif
       StubRoutines::call_stub()(
         (address)&link,
         // (intptr_t*)&(result->_value), // see NOTE above (compiler problem)
         result_val_address,          // see NOTE above (compiler problem)
         result_type,

@@ -450,12 +455,22 @@
       // Preserve oop return value across possible gc points
       if (oop_result_flag) {
         thread->set_vm_result((oop) result->get_jobject());
       }
     }
+#if INCLUDE_JVMCI
+    }
+#endif
   } // Exit JavaCallWrapper (can block - potential return oop must be preserved)
 
+  #if INCLUDE_JVMCI
+    if (entry_point == NULL) {
+      // Cannot creation exception until back in VM from Java
+      THROW(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException());
+    }
+  #endif
+
   // Check if a thread stop or suspend should be executed
   // The following assert was not realistic.  Thread.stop can set that bit at any moment.
   //assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed");
 
   // Restore possible oop return
< prev index next >