hotspot/src/share/vm/runtime/sharedRuntime.cpp
changeset 42650 1f304d0c888b
parent 42608 14af45789042
child 42664 29142a56c193
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Sun Dec 11 12:05:57 2016 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Sun Dec 11 19:07:04 2016 -0800
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "aot/aotLoader.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -79,6 +80,7 @@
 RuntimeStub*        SharedRuntime::_resolve_opt_virtual_call_blob;
 RuntimeStub*        SharedRuntime::_resolve_virtual_call_blob;
 RuntimeStub*        SharedRuntime::_resolve_static_call_blob;
+address             SharedRuntime::_resolve_static_call_entry;
 
 DeoptimizationBlob* SharedRuntime::_deopt_blob;
 SafepointBlob*      SharedRuntime::_polling_page_vectors_safepoint_handler_blob;
@@ -98,6 +100,7 @@
   _resolve_opt_virtual_call_blob       = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C),   "resolve_opt_virtual_call");
   _resolve_virtual_call_blob           = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C),       "resolve_virtual_call");
   _resolve_static_call_blob            = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),        "resolve_static_call");
+  _resolve_static_call_entry           = _resolve_static_call_blob->entry_point();
 
 #if defined(COMPILER2) || INCLUDE_JVMCI
   // Vectors are generated only by C2 and JVMCI.
@@ -476,7 +479,7 @@
   // JVMCI's ExceptionHandlerStub expects the thread local exception PC to be clear
   // and other exception handler continuations do not read it
   thread->set_exception_pc(NULL);
-#endif
+#endif // INCLUDE_JVMCI
 
   // The fastest case first
   CodeBlob* blob = CodeCache::find_blob(return_address);
@@ -504,6 +507,13 @@
     }
   }
 
+#if INCLUDE_AOT
+  if (UseAOT && blob->is_aot()) {
+    // AOT Compiled code
+    return AOTLoader::exception_begin(thread, blob, return_address);
+  }
+#endif
+
   // Entry code
   if (StubRoutines::returns_to_call_stub(return_address)) {
     return StubRoutines::catch_exception_entry();
@@ -989,17 +999,12 @@
 }
 
 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
-  assert(obj->is_oop(), "must be a valid oop");
 #if INCLUDE_JVMCI
-  // This removes the requirement for JVMCI compilers to emit code
-  // performing a dynamic check that obj has a finalizer before
-  // calling this routine. There should be no performance impact
-  // for C1 since it emits a dynamic check. C2 and the interpreter
-  // uses other runtime routines for registering finalizers.
   if (!obj->klass()->has_finalizer()) {
     return;
   }
 #endif // INCLUDE_JVMCI
+  assert(obj->is_oop(), "must be a valid oop");
   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
 JRT_END
@@ -1226,7 +1231,6 @@
     assert(fr.is_entry_frame(), "must be");
     // fr is now pointing to the entry frame.
     callee_method = methodHandle(THREAD, fr.entry_frame_call_wrapper()->callee_method());
-    assert(fr.entry_frame_call_wrapper()->receiver() == NULL || !callee_method->is_static(), "non-null receiver for static call??");
   } else {
     Bytecodes::Code bc;
     CallInfo callinfo;
@@ -1355,16 +1359,18 @@
   address dest_entry_point = callee == NULL ? 0 : callee->entry_point(); // used below
 #endif
 
+  bool is_nmethod = caller_nm->is_nmethod();
+
   if (is_virtual) {
     assert(receiver.not_null() || invoke_code == Bytecodes::_invokehandle, "sanity check");
     bool static_bound = call_info.resolved_method()->can_be_statically_bound();
     KlassHandle h_klass(THREAD, invoke_code == Bytecodes::_invokehandle ? NULL : receiver->klass());
     CompiledIC::compute_monomorphic_entry(callee_method, h_klass,
-                     is_optimized, static_bound, virtual_call_info,
+                     is_optimized, static_bound, is_nmethod, virtual_call_info,
                      CHECK_(methodHandle()));
   } else {
     // static call
-    CompiledStaticCall::compute_entry(callee_method, static_call_info);
+    CompiledStaticCall::compute_entry(callee_method, is_nmethod, static_call_info);
   }
 
   // grab lock, check for deoptimization and potentially patch caller
@@ -1395,7 +1401,7 @@
           inline_cache->set_to_monomorphic(virtual_call_info);
         }
       } else {
-        CompiledStaticCall* ssc = compiledStaticCall_before(caller_frame.pc());
+        CompiledStaticCall* ssc = caller_nm->compiledStaticCall_before(caller_frame.pc());
         if (ssc->is_clean()) ssc->set(static_call_info);
       }
     }
@@ -1511,6 +1517,7 @@
 JRT_END
 
 
+
 methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) {
   ResourceMark rm(thread);
   CallInfo call_info;
@@ -1623,7 +1630,7 @@
         inline_cache->compute_monomorphic_entry(callee_method,
                                                 receiver_klass,
                                                 inline_cache->is_optimized(),
-                                                false,
+                                                false, caller_nm->is_nmethod(),
                                                 info, CHECK_(methodHandle()));
         inline_cache->set_to_monomorphic(info);
       } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) {
@@ -1692,10 +1699,7 @@
       // busy patching it.
       MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
       // Location of call instruction
-      if (NativeCall::is_call_before(pc)) {
-        NativeCall *ncall = nativeCall_before(pc);
-        call_addr = ncall->instruction_address();
-      }
+      call_addr = caller_nm->call_instruction_address(pc);
     }
     // Make sure nmethod doesn't get deoptimized and removed until
     // this is done with it.
@@ -1725,9 +1729,10 @@
       // to a wrong method). It should not be performance critical, since the
       // resolve is only done once.
 
+      bool is_nmethod = caller_nm->is_nmethod();
       MutexLocker ml(CompiledIC_lock);
       if (is_static_call) {
-        CompiledStaticCall* ssc= compiledStaticCall_at(call_addr);
+        CompiledStaticCall* ssc = caller_nm->compiledStaticCall_at(call_addr);
         ssc->set_to_clean();
       } else {
         // compiled, dispatched call (which used to call an interpreted method)
@@ -1794,6 +1799,37 @@
 }
 #endif
 
+bool SharedRuntime::should_fixup_call_destination(address destination, address entry_point, address caller_pc, Method* moop, CodeBlob* cb) {
+  if (destination != entry_point) {
+    CodeBlob* callee = CodeCache::find_blob(destination);
+    // callee == cb seems weird. It means calling interpreter thru stub.
+    if (callee == cb || callee->is_adapter_blob()) {
+      // static call or optimized virtual
+      if (TraceCallFixup) {
+        tty->print("fixup callsite           at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
+        moop->print_short_name(tty);
+        tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
+      }
+      return true;
+    } else {
+      if (TraceCallFixup) {
+        tty->print("failed to fixup callsite at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
+        moop->print_short_name(tty);
+        tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
+      }
+      // assert is too strong could also be resolve destinations.
+      // assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be");
+    }
+  } else {
+    if (TraceCallFixup) {
+      tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
+      moop->print_short_name(tty);
+      tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
+    }
+  }
+  return false;
+}
+
 // ---------------------------------------------------------------------------
 // We are calling the interpreter via a c2i. Normally this would mean that
 // we were called by a compiled method. However we could have lost a race
@@ -1843,7 +1879,8 @@
     // Expect to find a native call there (unless it was no-inline cache vtable dispatch)
     MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
     if (NativeCall::is_call_before(return_pc)) {
-      NativeCall *call = nativeCall_before(return_pc);
+      ResourceMark mark;
+      NativeCallWrapper* call = nm->call_wrapper_before(return_pc);
       //
       // bug 6281185. We might get here after resolving a call site to a vanilla
       // virtual call. Because the resolvee uses the verified entry it may then
@@ -1864,32 +1901,8 @@
         return;
       }
       address destination = call->destination();
-      if (destination != entry_point) {
-        CodeBlob* callee = CodeCache::find_blob(destination);
-        // callee == cb seems weird. It means calling interpreter thru stub.
-        if (callee == cb || callee->is_adapter_blob()) {
-          // static call or optimized virtual
-          if (TraceCallFixup) {
-            tty->print("fixup callsite           at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
-            moop->print_short_name(tty);
-            tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
-          }
-          call->set_destination_mt_safe(entry_point);
-        } else {
-          if (TraceCallFixup) {
-            tty->print("failed to fixup callsite at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
-            moop->print_short_name(tty);
-            tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
-          }
-          // assert is too strong could also be resolve destinations.
-          // assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be");
-        }
-      } else {
-          if (TraceCallFixup) {
-            tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", p2i(caller_pc));
-            moop->print_short_name(tty);
-            tty->print_cr(" to " INTPTR_FORMAT, p2i(entry_point));
-          }
+      if (should_fixup_call_destination(destination, entry_point, caller_pc, moop, cb)) {
+        call->set_destination_mt_safe(entry_point);
       }
     }
   }