< prev index next >

hotspot/src/share/vm/c1/c1_GraphBuilder.cpp

Print this page
rev 11908 : 8160543: C1: Crash in java.lang.String.indexOf in some java.sql tests
Summary: C1 must use unverified entry point for unloaded methods.
Reviewed-by:

@@ -1797,24 +1797,23 @@
   ciSignature* declared_signature = NULL;
   ciMethod*             target = stream()->get_method(will_link, &declared_signature);
   ciKlass*              holder = stream()->get_declared_method_holder();
   const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
   assert(declared_signature != NULL, "cannot be null");
+  assert(will_link == target->is_loaded(), "Check");
 
   ciInstanceKlass* klass = target->holder();
 
-  // Make sure there are no evident problems with linking the instruction.
-  bool is_resolved = true;
-  if (klass->is_loaded() && !target->is_loaded()) {
-    is_resolved = false; // method not found
-  }
-
   // check if CHA possible: if so, change the code to invoke_special
   ciInstanceKlass* calling_klass = method()->holder();
   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
   ciInstanceKlass* actual_recv = callee_holder;
 
+  if (target->is_loaded()) {
+    assert(klass->is_loaded(), "sanity");
+  }
+
   CompileLog* log = compilation()->log();
   if (log != NULL)
       log->elem("call method='%d' instr='%s'",
                 log->identify(target),
                 Bytecodes::name(code));

@@ -1972,11 +1971,11 @@
     }
     code = Bytecodes::_invokespecial;
   }
 
   // check if we could do inlining
-  if (!PatchALot && Inline && is_resolved &&
+  if (!PatchALot && Inline &&
       klass->is_loaded() && target->is_loaded() &&
       (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
       && !patch_for_appendix) {
     // callee is known => check if we have static binding
     if (code == Bytecodes::_invokestatic  ||

@@ -2016,11 +2015,10 @@
   // corrupting the graph. (We currently bail out with a non-empty
   // stack at a ret in these situations.)
   CHECK_BAILOUT();
 
   // inlining not successful => standard invoke
-  bool is_loaded = target->is_loaded();
   ValueType* result_type = as_ValueType(declared_signature->return_type());
   ValueStack* state_before = copy_state_exhandling();
 
   // The bytecode (code) might change in this method so we are checking this very late.
   const bool has_receiver =

@@ -2033,11 +2031,11 @@
 
 #ifdef SPARC
   // Currently only supported on Sparc.
   // The UseInlineCaches only controls dispatch to invokevirtuals for
   // loaded classes which we weren't able to statically bind.
-  if (!UseInlineCaches && is_resolved && is_loaded && code == Bytecodes::_invokevirtual
+  if (!UseInlineCaches && target->is_loaded() && code == Bytecodes::_invokevirtual
       && !target->can_be_statically_bound()) {
     // Find a vtable index if one is available
     // For arrays, callee_holder is Object. Resolving the call with
     // Object would allow an illegal call to finalize() on an
     // array. We use holder instead: illegal calls to finalize() won't

@@ -2046,22 +2044,22 @@
     // either.
     vtable_index = target->resolve_vtable_index(calling_klass, holder);
   }
 #endif
 
-  if (is_resolved) {
+
     // invokespecial always needs a NULL check. invokevirtual where the target is
     // final or where it's not known whether the target is final requires a NULL check.
     // Otherwise normal invokevirtual will perform the null check during the lookup
     // logic or the unverified entry point.  Profiling of calls requires that
     // the null check is performed in all cases.
+
     bool do_null_check = (recv != NULL) &&
-        (code == Bytecodes::_invokespecial || !is_loaded || target->is_final() || (is_profiling() && profile_calls()));
+      (code == Bytecodes::_invokespecial || (target->is_loaded() && (target->is_final() || (is_profiling() && profile_calls()))));
 
     if (do_null_check) {
       null_check(recv);
-    }
 
     if (is_profiling()) {
       // Note that we'd collect profile data in this method if we wanted it.
       compilation()->set_would_profile(true);
 

@@ -2074,13 +2072,10 @@
           target_klass = exact_target->holder();
         }
         profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false);
       }
     }
-  } else {
-    // No need in null check or profiling: linkage error will be thrown at runtime
-    // during resolution.
   }
 
   Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
   // push result
   append_split(result);
< prev index next >