< 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,1820 **** 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"); 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; CompileLog* log = compilation()->log(); if (log != NULL) log->elem("call method='%d' instr='%s'", log->identify(target), Bytecodes::name(code)); --- 1797,1819 ---- 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(); // 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,1982 **** } code = Bytecodes::_invokespecial; } // check if we could do inlining ! if (!PatchALot && Inline && is_resolved && 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 || --- 1971,1981 ---- } code = Bytecodes::_invokespecial; } // check if we could do inlining ! 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,2026 **** // 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 = --- 2015,2024 ----
*** 2033,2043 **** #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 && !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 --- 2031,2041 ---- #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 && 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,2067 **** // 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())); 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); --- 2044,2065 ---- // either. vtable_index = target->resolve_vtable_index(calling_klass, holder); } #endif ! // 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 || (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,2086 **** 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); --- 2072,2081 ----
< prev index next >