src/hotspot/share/interpreter/abstractInterpreter.cpp
changeset 54723 1abca1170080
parent 53193 184c51e48260
child 58096 0d97bf7cf8a4
--- a/src/hotspot/share/interpreter/abstractInterpreter.cpp	Mon May 06 12:15:55 2019 -0700
+++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp	Mon May 06 12:17:54 2019 -0700
@@ -28,6 +28,7 @@
 #include "compiler/disassembler.hpp"
 #include "interpreter/bytecodeHistogram.hpp"
 #include "interpreter/bytecodeInterpreter.hpp"
+#include "interpreter/bytecodeStream.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "interpreter/interp_masm.hpp"
@@ -36,6 +37,8 @@
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/arrayOop.hpp"
+#include "oops/constantPool.hpp"
+#include "oops/cpCache.inline.hpp"
 #include "oops/methodData.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
@@ -240,9 +243,36 @@
 // Return true if the interpreter can prove that the given bytecode has
 // not yet been executed (in Java semantics, not in actual operation).
 bool AbstractInterpreter::is_not_reached(const methodHandle& method, int bci) {
-  Bytecodes::Code code = method()->code_at(bci);
+  BytecodeStream s(method, bci);
+  Bytecodes::Code code = s.next();
+
+  if (Bytecodes::is_invoke(code)) {
+    assert(!Bytecodes::must_rewrite(code), "invokes aren't rewritten");
+    ConstantPool* cpool = method()->constants();
+
+    Bytecode invoke_bc(s.bytecode());
 
-  if (!Bytecodes::must_rewrite(code)) {
+    switch (code) {
+      case Bytecodes::_invokedynamic: {
+        assert(invoke_bc.has_index_u4(code), "sanity");
+        int method_index = invoke_bc.get_index_u4(code);
+        return cpool->invokedynamic_cp_cache_entry_at(method_index)->is_f1_null();
+      }
+      case Bytecodes::_invokevirtual:   // fall-through
+      case Bytecodes::_invokeinterface: // fall-through
+      case Bytecodes::_invokespecial:   // fall-through
+      case Bytecodes::_invokestatic: {
+        if (cpool->has_preresolution()) {
+          return false; // might have been reached
+        }
+        assert(!invoke_bc.has_index_u4(code), "sanity");
+        int method_index = invoke_bc.get_index_u2_cpcache(code);
+        Method* resolved_method = ConstantPool::method_at_if_loaded(cpool, method_index);
+        return (resolved_method == NULL);
+      }
+      default: ShouldNotReachHere();
+    }
+  } else if (!Bytecodes::must_rewrite(code)) {
     // might have been reached
     return false;
   }