# HG changeset patch # User never # Date 1331310876 28800 # Node ID d8b13355c5008d3668961892a910fadc4f7cd049 # Parent 541c4a5e7b88210894fe86b50ce2cd7687239478# Parent d59a6302465aaac406880e4db711ea02305d7d75 Merge diff -r d59a6302465a -r d8b13355c500 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Mar 09 08:34:36 2012 -0800 @@ -1306,6 +1306,7 @@ if (sw.dest_offset_at(i) < 0) has_bb = true; } // add default successor + if (sw.default_offset() < 0) has_bb = true; sux->at_put(i, block_at(bci() + sw.default_offset())); ValueStack* state_before = has_bb ? copy_state_before() : NULL; Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb)); @@ -1350,6 +1351,7 @@ keys->at_put(i, pair.match()); } // add default successor + if (sw.default_offset() < 0) has_bb = true; sux->at_put(i, block_at(bci() + sw.default_offset())); ValueStack* state_before = has_bb ? copy_state_before() : NULL; Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb)); diff -r d59a6302465a -r d8b13355c500 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/opto/compile.hpp Fri Mar 09 08:34:36 2012 -0800 @@ -631,7 +631,7 @@ // Decide how to build a call. // The profile factor is a discount to apply to this site's interp. profile. - CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor); + CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true); bool should_delay_inlining(ciMethod* call_method, JVMState* jvms); // Report if there were too many traps at a current method and bci. diff -r d59a6302465a -r d8b13355c500 src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/opto/doCall.cpp Fri Mar 09 08:34:36 2012 -0800 @@ -61,7 +61,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, - float prof_factor) { + float prof_factor, bool allow_intrinsics) { ciMethod* caller = jvms->method(); int bci = jvms->bci(); Bytecodes::Code bytecode = caller->java_code_at_bci(bci); @@ -108,7 +108,7 @@ // then we return it as the inlined version of the call. // We do this before the strict f.p. check below because the // intrinsics handle strict f.p. correctly. - if (allow_inline) { + if (allow_inline && allow_intrinsics) { CallGenerator* cg = find_intrinsic(call_method, call_is_virtual); if (cg != NULL) return cg; } @@ -455,21 +455,12 @@ // cg->generate(), we are committed. If it fails, the whole // compilation task is compromised. if (failing()) return; -#ifndef PRODUCT - if (PrintOpto || PrintOptoInlining || PrintInlining) { - // Only one fall-back, so if an intrinsic fails, ignore any bytecodes. - if (cg->is_intrinsic() && call_method->code_size() > 0) { - tty->print("Bailed out of intrinsic, will not inline: "); - call_method->print_name(); tty->cr(); - } - } -#endif + // This can happen if a library intrinsic is available, but refuses // the call site, perhaps because it did not match a pattern the - // intrinsic was expecting to optimize. The fallback position is - // to call out-of-line. - try_inline = false; // Inline tactic bailed out. - cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor()); + // intrinsic was expecting to optimize. Should always be possible to + // get a normal java call that may inline in that case + cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); if ((new_jvms = cg->generate(jvms)) == NULL) { guarantee(failing(), "call failed to generate: calls should work"); return; diff -r d59a6302465a -r d8b13355c500 src/share/vm/opto/library_call.cpp --- a/src/share/vm/opto/library_call.cpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/opto/library_call.cpp Fri Mar 09 08:34:36 2012 -0800 @@ -338,8 +338,27 @@ break; case vmIntrinsics::_bitCount_i: + if (!Matcher::has_match_rule(Op_PopCountI)) return NULL; + break; + case vmIntrinsics::_bitCount_l: - if (!UsePopCountInstruction) return NULL; + if (!Matcher::has_match_rule(Op_PopCountL)) return NULL; + break; + + case vmIntrinsics::_numberOfLeadingZeros_i: + if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL; + break; + + case vmIntrinsics::_numberOfLeadingZeros_l: + if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL; + break; + + case vmIntrinsics::_numberOfTrailingZeros_i: + if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL; + break; + + case vmIntrinsics::_numberOfTrailingZeros_l: + if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL; break; case vmIntrinsics::_Reference_get: @@ -416,14 +435,12 @@ return kit.transfer_exceptions_into_jvms(); } - if (PrintIntrinsics) { + // The intrinsic bailed out + if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { if (jvms->has_method()) { // Not a root compile. - tty->print("Did not inline intrinsic %s%s at bci:%d in", - vmIntrinsics::name_at(intrinsic_id()), - (is_virtual() ? " (virtual)" : ""), kit.bci()); - kit.caller()->print_short_name(tty); - tty->print_cr(" (%d bytes)", kit.caller()->code_size()); + const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)"; + CompileTask::print_inlining(kit.callee(), jvms->depth() - 1, kit.bci(), msg); } else { // Root compile tty->print("Did not generate intrinsic %s%s at bci:%d in", @@ -5453,4 +5470,3 @@ push(result); return true; } - diff -r d59a6302465a -r d8b13355c500 src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/runtime/safepoint.cpp Fri Mar 09 08:34:36 2012 -0800 @@ -219,6 +219,8 @@ #ifdef ASSERT for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) { assert(cur->safepoint_state()->is_running(), "Illegal initial state"); + // Clear the visited flag to ensure that the critical counts are collected properly. + cur->set_visited_for_critical_count(false); } #endif // ASSERT @@ -378,6 +380,13 @@ OrderAccess::fence(); +#ifdef ASSERT + for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) { + // make sure all the threads were visited + assert(cur->was_visited_for_critical_count(), "missed a thread"); + } +#endif // ASSERT + // Update the count of active JNI critical regions GC_locker::set_jni_lock_count(_current_jni_active_count); @@ -626,6 +635,7 @@ _waiting_to_block--; thread->safepoint_state()->set_has_called_back(true); + DEBUG_ONLY(thread->set_visited_for_critical_count(true)); if (thread->in_critical()) { // Notice that this thread is in a critical section increment_jni_active_count(); @@ -907,12 +917,8 @@ // running, but are actually at a safepoint. We will happily // agree and update the safepoint state here. if (SafepointSynchronize::safepoint_safe(_thread, state)) { + SafepointSynchronize::check_for_lazy_critical_native(_thread, state); roll_forward(_at_safepoint); - SafepointSynchronize::check_for_lazy_critical_native(_thread, state); - if (_thread->in_critical()) { - // Notice that this thread is in a critical section - SafepointSynchronize::increment_jni_active_count(); - } return; } @@ -937,6 +943,11 @@ switch(_type) { case _at_safepoint: SafepointSynchronize::signal_thread_at_safepoint(); + DEBUG_ONLY(_thread->set_visited_for_critical_count(true)); + if (_thread->in_critical()) { + // Notice that this thread is in a critical section + SafepointSynchronize::increment_jni_active_count(); + } break; case _call_back: diff -r d59a6302465a -r d8b13355c500 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/runtime/thread.cpp Fri Mar 09 08:34:36 2012 -0800 @@ -247,6 +247,10 @@ omInUseList = NULL ; omInUseCount = 0 ; +#ifdef ASSERT + _visited_for_critical_count = false; +#endif + _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true); _suspend_flags = 0; diff -r d59a6302465a -r d8b13355c500 src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Fri Mar 09 00:28:20 2012 -0500 +++ b/src/share/vm/runtime/thread.hpp Fri Mar 09 08:34:36 2012 -0800 @@ -268,6 +268,15 @@ ObjectMonitor* omInUseList; // SLL to track monitors in circulation int omInUseCount; // length of omInUseList +#ifdef ASSERT + private: + bool _visited_for_critical_count; + + public: + void set_visited_for_critical_count(bool z) { _visited_for_critical_count = z; } + bool was_visited_for_critical_count() const { return _visited_for_critical_count; } +#endif + public: enum { is_definitely_current_thread = true