# HG changeset patch # User kvn # Date 1241804660 25200 # Node ID 69187054225f0417307cd961f155dade09002e95 # Parent 6beb2b47717a6d0fa87440973e665105e476ad8b 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits Summary: Cache Jvmti and DTrace flags used by Compiler. Reviewed-by: never diff -r 6beb2b47717a -r 69187054225f hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri May 08 10:44:20 2009 -0700 @@ -378,7 +378,7 @@ compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset()); - if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) { + if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) { __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type); __ delayed()->nop(); } diff -r 6beb2b47717a -r 69187054225f hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri May 08 10:44:20 2009 -0700 @@ -286,7 +286,7 @@ initialize_body(base, index); } - if (DTraceAllocProbes) { + if (CURRENT_ENV->dtrace_alloc_probes()) { assert(obj == O0, "must be"); call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), relocInfo::runtime_call_type); @@ -355,7 +355,7 @@ sub(arr_size, hdr_size * wordSize, index); // compute index = number of words to clear initialize_body(base, index); - if (DTraceAllocProbes) { + if (CURRENT_ENV->dtrace_alloc_probes()) { assert(obj == O0, "must be"); call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), relocInfo::runtime_call_type); diff -r 6beb2b47717a -r 69187054225f hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri May 08 10:44:20 2009 -0700 @@ -439,7 +439,7 @@ // if the method does not have an exception handler, then there is // no reason to search for one - if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) { + if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) { // the exception oop and pc are in rax, and rdx // no other registers need to be preserved, so invalidate them __ invalidate_registers(false, true, true, false, true, true); diff -r 6beb2b47717a -r 69187054225f hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri May 08 10:44:20 2009 -0700 @@ -258,7 +258,7 @@ } } - if (DTraceAllocProbes) { + if (CURRENT_ENV->dtrace_alloc_probes()) { assert(obj == rax, "must be"); call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id))); } @@ -291,7 +291,7 @@ const Register len_zero = len; initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero); - if (DTraceAllocProbes) { + if (CURRENT_ENV->dtrace_alloc_probes()) { assert(obj == rax, "must be"); call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id))); } diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/c1/c1_Compilation.cpp --- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri May 08 10:44:20 2009 -0700 @@ -319,7 +319,7 @@ return; } - if (JvmtiExport::can_hotswap_or_post_breakpoint()) { + if (_env->jvmti_can_hotswap_or_post_breakpoint()) { // We can assert evol_method because method->can_be_compiled is true. dependency_recorder()->assert_evol_method(method()); } @@ -435,7 +435,7 @@ assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time"); _arena = Thread::current()->resource_area(); _compilation = this; - _needs_debug_information = JvmtiExport::can_examine_or_deopt_anywhere() || + _needs_debug_information = _env->jvmti_can_examine_or_deopt_anywhere() || JavaMonitorsInStackTrace || AlwaysEmitDebugInfo || DeoptimizeALot; _exception_info_list = new ExceptionInfoList(); _implicit_exception_table.set_size(0); diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri May 08 10:44:20 2009 -0700 @@ -1662,7 +1662,7 @@ // Register dependence if JVMTI has either breakpoint // setting or hotswapping of methods capabilities since they may // cause deoptimization. - if (JvmtiExport::can_hotswap_or_post_breakpoint()) { + if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) { dependency_recorder()->assert_evol_method(inline_target); } return; @@ -2863,7 +2863,7 @@ start_block->merge(_initial_state); BlockBegin* sync_handler = NULL; - if (method()->is_synchronized() || DTraceMethodProbes) { + if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) { // setup an exception handler to do the unlocking and/or notification sync_handler = new BlockBegin(-1); sync_handler->set(BlockBegin::exception_entry_flag); diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri May 08 10:44:20 2009 -0700 @@ -1064,7 +1064,7 @@ void LIRGenerator::do_Return(Return* x) { - if (DTraceMethodProbes) { + if (compilation()->env()->dtrace_method_probes()) { BasicTypeList signature; signature.append(T_INT); // thread signature.append(T_OBJECT); // methodOop @@ -1769,7 +1769,7 @@ __ null_check(exception_opr, new CodeEmitInfo(info, true)); } - if (JvmtiExport::can_post_exceptions() && + if (compilation()->env()->jvmti_can_post_exceptions() && !block()->is_set(BlockBegin::default_exception_handler_flag)) { // we need to go through the exception lookup path to get JVMTI // notification done @@ -1779,7 +1779,7 @@ assert(!block()->is_set(BlockBegin::default_exception_handler_flag) || unwind, "should be no more handlers to dispatch to"); - if (DTraceMethodProbes && + if (compilation()->env()->dtrace_method_probes() && block()->is_set(BlockBegin::default_exception_handler_flag)) { // notify that this frame is unwinding BasicTypeList signature; @@ -2204,7 +2204,7 @@ java_index += type2size[t]; } - if (DTraceMethodProbes) { + if (compilation()->env()->dtrace_method_probes()) { BasicTypeList signature; signature.append(T_INT); // thread signature.append(T_OBJECT); // methodOop diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri May 08 10:44:20 2009 -0700 @@ -171,6 +171,34 @@ } // ------------------------------------------------------------------ +// Cache Jvmti state +void ciEnv::cache_jvmti_state() { + VM_ENTRY_MARK; + // Get Jvmti capabilities under lock to get consistant values. + MutexLocker mu(JvmtiThreadState_lock); + _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); + _jvmti_can_examine_or_deopt_anywhere = JvmtiExport::can_examine_or_deopt_anywhere(); + _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); + _jvmti_can_post_exceptions = JvmtiExport::can_post_exceptions(); +} + +// ------------------------------------------------------------------ +// Cache DTrace flags +void ciEnv::cache_dtrace_flags() { + // Need lock? + _dtrace_extended_probes = ExtendedDTraceProbes; + if (_dtrace_extended_probes) { + _dtrace_monitor_probes = true; + _dtrace_method_probes = true; + _dtrace_alloc_probes = true; + } else { + _dtrace_monitor_probes = DTraceMonitorProbes; + _dtrace_method_probes = DTraceMethodProbes; + _dtrace_alloc_probes = DTraceAllocProbes; + } +} + +// ------------------------------------------------------------------ // helper for lazy exception creation ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) { VM_ENTRY_MARK; @@ -810,16 +838,39 @@ // and invalidating our dependencies until we install this method. MutexLocker ml(Compile_lock); - if (log() != NULL) { - // Log the dependencies which this compilation declares. - dependencies()->log_all_dependencies(); + // Change in Jvmti state may invalidate compilation. + if (!failing() && + ( (!jvmti_can_hotswap_or_post_breakpoint() && + JvmtiExport::can_hotswap_or_post_breakpoint()) || + (!jvmti_can_examine_or_deopt_anywhere() && + JvmtiExport::can_examine_or_deopt_anywhere()) || + (!jvmti_can_access_local_variables() && + JvmtiExport::can_access_local_variables()) || + (!jvmti_can_post_exceptions() && + JvmtiExport::can_post_exceptions()) )) { + record_failure("Jvmti state change invalidated dependencies"); } - // Encode the dependencies now, so we can check them right away. - dependencies()->encode_content_bytes(); + // Change in DTrace flags may invalidate compilation. + if (!failing() && + ( (!dtrace_extended_probes() && ExtendedDTraceProbes) || + (!dtrace_method_probes() && DTraceMethodProbes) || + (!dtrace_alloc_probes() && DTraceAllocProbes) )) { + record_failure("DTrace flags change invalidated dependencies"); + } - // Check for {class loads, evolution, breakpoints} during compilation - check_for_system_dictionary_modification(target); + if (!failing()) { + if (log() != NULL) { + // Log the dependencies which this compilation declares. + dependencies()->log_all_dependencies(); + } + + // Encode the dependencies now, so we can check them right away. + dependencies()->encode_content_bytes(); + + // Check for {class loads, evolution, breakpoints} during compilation + check_for_system_dictionary_modification(target); + } methodHandle method(THREAD, target->get_methodOop()); diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/ci/ciEnv.hpp --- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/ci/ciEnv.hpp Fri May 08 10:44:20 2009 -0700 @@ -53,6 +53,18 @@ char* _name_buffer; int _name_buffer_len; + // Cache Jvmti state + bool _jvmti_can_hotswap_or_post_breakpoint; + bool _jvmti_can_examine_or_deopt_anywhere; + bool _jvmti_can_access_local_variables; + bool _jvmti_can_post_exceptions; + + // Cache DTrace flags + bool _dtrace_extended_probes; + bool _dtrace_monitor_probes; + bool _dtrace_method_probes; + bool _dtrace_alloc_probes; + // Distinguished instances of certain ciObjects.. static ciObject* _null_object_instance; static ciMethodKlass* _method_klass_instance; @@ -236,6 +248,20 @@ bool break_at_compile() { return _break_at_compile; } void set_break_at_compile(bool z) { _break_at_compile = z; } + // Cache Jvmti state + void cache_jvmti_state(); + bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; } + bool jvmti_can_examine_or_deopt_anywhere() const { return _jvmti_can_examine_or_deopt_anywhere; } + bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; } + bool jvmti_can_post_exceptions() const { return _jvmti_can_post_exceptions; } + + // Cache DTrace flags + void cache_dtrace_flags(); + bool dtrace_extended_probes() const { return _dtrace_extended_probes; } + bool dtrace_monitor_probes() const { return _dtrace_monitor_probes; } + bool dtrace_method_probes() const { return _dtrace_method_probes; } + bool dtrace_alloc_probes() const { return _dtrace_alloc_probes; } + // The compiler task which has created this env. // May be useful to find out compile_id, comp_level, etc. CompileTask* task() { return _task; } diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/ci/ciMethod.cpp --- a/hotspot/src/share/vm/ci/ciMethod.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri May 08 10:44:20 2009 -0700 @@ -60,7 +60,8 @@ _flow = NULL; #endif // COMPILER2 - if (JvmtiExport::can_hotswap_or_post_breakpoint() && _is_compilable) { + ciEnv *env = CURRENT_ENV; + if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) { // 6328518 check hotswap conditions under the right lock. MutexLocker locker(Compile_lock); if (Dependencies::check_evol_method(h_m()) != NULL) { @@ -84,7 +85,6 @@ if (_can_be_statically_bound && h_m()->is_abstract()) _can_be_statically_bound = false; - ciEnv *env = CURRENT_ENV; // generating _signature may allow GC and therefore move m. // These fields are always filled in. _name = env->get_object(h_m()->name())->as_symbol(); @@ -337,7 +337,7 @@ _liveness->compute_liveness(); } MethodLivenessResult result = _liveness->get_liveness_at(bci); - if (JvmtiExport::can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { + if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { // Keep all locals live for the user's edification and amusement. result.at_put_range(0, result.size(), true); } diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/compiler/compileBroker.cpp --- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri May 08 10:44:20 2009 -0700 @@ -1530,6 +1530,12 @@ assert(thread->env() == &ci_env, "set by ci_env"); // The thread-env() field is cleared in ~CompileTaskWrapper. + // Cache Jvmti state + ci_env.cache_jvmti_state(); + + // Cache DTrace flags + ci_env.cache_dtrace_flags(); + ciMethod* target = ci_env.get_method_from_handle(target_handle); TraceTime t1("compilation", &time); diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/opto/doCall.cpp --- a/hotspot/src/share/vm/opto/doCall.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/opto/doCall.cpp Fri May 08 10:44:20 2009 -0700 @@ -47,7 +47,7 @@ CallGenerator* cg; // Dtrace currently doesn't work unless all calls are vanilla - if (DTraceMethodProbes) { + if (env()->dtrace_method_probes()) { allow_inline = false; } diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Fri May 08 10:44:20 2009 -0700 @@ -459,7 +459,7 @@ void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) { bool must_throw = true; - if (JvmtiExport::can_post_exceptions()) { + if (env()->jvmti_can_post_exceptions()) { // Do not try anything fancy if we're notifying the VM on every throw. // Cf. case Bytecodes::_athrow in parse2.cpp. uncommon_trap(reason, Deoptimization::Action_none, @@ -769,7 +769,7 @@ } } - if (JvmtiExport::can_examine_or_deopt_anywhere()) { + if (env()->jvmti_can_examine_or_deopt_anywhere()) { // At any safepoint, this method can get breakpointed, which would // then require an immediate deoptimization. full_info = true; diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/opto/macro.cpp Fri May 08 10:44:20 2009 -0700 @@ -988,7 +988,7 @@ initial_slow_test = BoolNode::make_predicate(initial_slow_test, &_igvn); } - if (DTraceAllocProbes || + if (C->env()->dtrace_alloc_probes() || !UseTLAB && (!Universe::heap()->supports_inline_contig_alloc() || (UseConcMarkSweepGC && CMSIncrementalMode))) { // Force slow-path allocation @@ -1150,7 +1150,7 @@ fast_oop_ctrl, fast_oop_rawmem, fast_oop, klass_node, length, size_in_bytes); - if (ExtendedDTraceProbes) { + if (C->env()->dtrace_extended_probes()) { // Slow-path call int size = TypeFunc::Parms + 2; CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/opto/parse1.cpp --- a/hotspot/src/share/vm/opto/parse1.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/opto/parse1.cpp Fri May 08 10:44:20 2009 -0700 @@ -439,7 +439,7 @@ // Always register dependence if JVMTI is enabled, because // either breakpoint setting or hotswapping of methods may // cause deoptimization. - if (JvmtiExport::can_hotswap_or_post_breakpoint()) { + if (C->env()->jvmti_can_hotswap_or_post_breakpoint()) { C->dependencies()->assert_evol_method(method()); } @@ -953,7 +953,7 @@ bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode; // record exit from a method if compiled while Dtrace is turned on. - if (do_synch || DTraceMethodProbes) { + if (do_synch || C->env()->dtrace_method_probes()) { // First move the exception list out of _exits: GraphKit kit(_exits.transfer_exceptions_into_jvms()); SafePointNode* normal_map = kit.map(); // keep this guy safe @@ -975,7 +975,7 @@ // Unlock! kit.shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node()); } - if (DTraceMethodProbes) { + if (C->env()->dtrace_method_probes()) { kit.make_dtrace_method_exit(method()); } // Done with exception-path processing. @@ -1074,7 +1074,7 @@ NOT_PRODUCT( count_compiled_calls(true/*at_method_entry*/, false/*is_inline*/); ) - if (DTraceMethodProbes) { + if (C->env()->dtrace_method_probes()) { make_dtrace_method_entry(method()); } @@ -1960,7 +1960,7 @@ if (method()->is_synchronized() && GenerateSynchronizationCode) { shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node()); } - if (DTraceMethodProbes) { + if (C->env()->dtrace_method_probes()) { make_dtrace_method_exit(method()); } SafePointNode* exit_return = _exits.map(); diff -r 6beb2b47717a -r 69187054225f hotspot/src/share/vm/opto/parse2.cpp --- a/hotspot/src/share/vm/opto/parse2.cpp Fri May 08 10:34:31 2009 -0700 +++ b/hotspot/src/share/vm/opto/parse2.cpp Fri May 08 10:44:20 2009 -0700 @@ -2052,7 +2052,7 @@ // null exception oop throws NULL pointer exception do_null_check(peek(), T_OBJECT); if (stopped()) return; - if (JvmtiExport::can_post_exceptions()) { + if (env()->jvmti_can_post_exceptions()) { // "Full-speed throwing" is not necessary here, // since we're notifying the VM on every throw. uncommon_trap(Deoptimization::Reason_unhandled,