# HG changeset patch # User mgronlun # Date 1393060925 -3600 # Node ID 96d2c94bbdd06ae58cc3dc3529a902131ac67abe # Parent 4510a35021667cf5c40413d6ce17b3c017dc2191 8035493: JVMTI PopFrame capability must instruct compilers not to prune locals Reviewed-by: kvn, sla, coleenp, sspitsyn diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -2276,7 +2276,7 @@ if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) { assert(instruction->exception_state() == NULL || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState - || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()), + || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->should_retain_local_variables()), "exception_state should be of exception kind"); return new XHandlers(); } @@ -2367,7 +2367,7 @@ // This scope and all callees do not handle exceptions, so the local // variables of this scope are not needed. However, the scope itself is // required for a correct exception stack trace -> clear out the locals. - if (_compilation->env()->jvmti_can_access_local_variables()) { + if (_compilation->env()->should_retain_local_variables()) { cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); } else { cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci()); @@ -3251,7 +3251,7 @@ ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) { ValueStack* s = copy_state_exhandling_with_bci(bci); if (s == NULL) { - if (_compilation->env()->jvmti_can_access_local_variables()) { + if (_compilation->env()->should_retain_local_variables()) { s = state()->copy(ValueStack::ExceptionState, bci); } else { s = state()->copy(ValueStack::EmptyExceptionState, bci); diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/c1/c1_Instruction.cpp --- a/src/share/vm/c1/c1_Instruction.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/c1/c1_Instruction.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -76,7 +76,7 @@ void Instruction::update_exception_state(ValueStack* state) { if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) { - assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind"); + assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->should_retain_local_variables(), "unexpected state kind"); _exception_state = state; } else { _exception_state = NULL; diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/c1/c1_ValueStack.cpp --- a/src/share/vm/c1/c1_ValueStack.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/c1/c1_ValueStack.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -52,7 +52,7 @@ , _stack() , _locks(copy_from->locks_size()) { - assert(kind != EmptyExceptionState || !Compilation::current()->env()->jvmti_can_access_local_variables(), "need locals"); + assert(kind != EmptyExceptionState || !Compilation::current()->env()->should_retain_local_variables(), "need locals"); if (kind != EmptyExceptionState) { // only allocate space if we need to copy the locals-array _locals = Values(copy_from->locals_size()); diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/c1/c1_ValueStack.hpp --- a/src/share/vm/c1/c1_ValueStack.hpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/c1/c1_ValueStack.hpp Sat Feb 22 10:22:05 2014 +0100 @@ -75,7 +75,7 @@ void set_caller_state(ValueStack* s) { assert(kind() == EmptyExceptionState || - (Compilation::current()->env()->jvmti_can_access_local_variables() && kind() == ExceptionState), + (Compilation::current()->env()->should_retain_local_variables() && kind() == ExceptionState), "only EmptyExceptionStates can be modified"); _caller_state = s; } diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/ci/ciEnv.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -136,6 +136,11 @@ _ClassCastException_instance = NULL; _the_null_string = NULL; _the_min_jint_string = NULL; + + _jvmti_can_hotswap_or_post_breakpoint = false; + _jvmti_can_access_local_variables = false; + _jvmti_can_post_on_exceptions = false; + _jvmti_can_pop_frame = false; } ciEnv::ciEnv(Arena* arena) { @@ -186,6 +191,11 @@ _ClassCastException_instance = NULL; _the_null_string = NULL; _the_min_jint_string = NULL; + + _jvmti_can_hotswap_or_post_breakpoint = false; + _jvmti_can_access_local_variables = false; + _jvmti_can_post_on_exceptions = false; + _jvmti_can_pop_frame = false; } ciEnv::~ciEnv() { @@ -205,6 +215,31 @@ _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); + _jvmti_can_pop_frame = JvmtiExport::can_pop_frame(); +} + +bool ciEnv::should_retain_local_variables() const { + return _jvmti_can_access_local_variables || _jvmti_can_pop_frame; +} + +bool ciEnv::jvmti_state_changed() const { + if (!_jvmti_can_access_local_variables && + JvmtiExport::can_access_local_variables()) { + return true; + } + if (!_jvmti_can_hotswap_or_post_breakpoint && + JvmtiExport::can_hotswap_or_post_breakpoint()) { + return true; + } + if (!_jvmti_can_post_on_exceptions && + JvmtiExport::can_post_on_exceptions()) { + return true; + } + if (!_jvmti_can_pop_frame && + JvmtiExport::can_pop_frame()) { + return true; + } + return false; } // ------------------------------------------------------------------ @@ -940,13 +975,7 @@ No_Safepoint_Verifier nsv; // Change in Jvmti state may invalidate compilation. - if (!failing() && - ( (!jvmti_can_hotswap_or_post_breakpoint() && - JvmtiExport::can_hotswap_or_post_breakpoint()) || - (!jvmti_can_access_local_variables() && - JvmtiExport::can_access_local_variables()) || - (!jvmti_can_post_on_exceptions() && - JvmtiExport::can_post_on_exceptions()) )) { + if (!failing() && jvmti_state_changed()) { record_failure("Jvmti state change invalidated dependencies"); } diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/ci/ciEnv.hpp Sat Feb 22 10:22:05 2014 +0100 @@ -69,6 +69,7 @@ bool _jvmti_can_hotswap_or_post_breakpoint; bool _jvmti_can_access_local_variables; bool _jvmti_can_post_on_exceptions; + bool _jvmti_can_pop_frame; // Cache DTrace flags bool _dtrace_extended_probes; @@ -332,8 +333,9 @@ // Cache Jvmti state void cache_jvmti_state(); + bool jvmti_state_changed() const; + bool should_retain_local_variables() const; bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; } - bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; } bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions; } // Cache DTrace flags diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/ci/ciMethod.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -412,7 +412,7 @@ // information. MethodLivenessResult ciMethod::liveness_at_bci(int bci) { MethodLivenessResult result = raw_liveness_at_bci(bci); - if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { + if (CURRENT_ENV->should_retain_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 4510a3502166 -r 96d2c94bbdd0 src/share/vm/opto/c2compiler.cpp --- a/src/share/vm/opto/c2compiler.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/opto/c2compiler.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -111,7 +111,7 @@ assert(is_initialized(), "Compiler thread must be initialized"); bool subsume_loads = SubsumeLoads; - bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); + bool do_escape_analysis = DoEscapeAnalysis && !env->should_retain_local_variables(); bool eliminate_boxing = EliminateAutoBox; while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions. diff -r 4510a3502166 -r 96d2c94bbdd0 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Thu Feb 20 16:38:45 2014 -0500 +++ b/src/share/vm/opto/graphKit.cpp Sat Feb 22 10:22:05 2014 +0100 @@ -863,7 +863,7 @@ } } - if (env()->jvmti_can_access_local_variables()) { + if (env()->should_retain_local_variables()) { // At any safepoint, this method can get breakpointed, which would // then require an immediate deoptimization. can_prune_locals = false; // do not prune locals