8035493: JVMTI PopFrame capability must instruct compilers not to prune locals
Reviewed-by: kvn, sla, coleenp, sspitsyn
This commit is contained in:
parent
70c77b3470
commit
68857c9469
@ -2276,7 +2276,7 @@ XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
|
||||
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 @@ XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
|
||||
// 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_exhandling_with_bci(int bci) {
|
||||
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);
|
||||
|
@ -76,7 +76,7 @@ Instruction::Condition Instruction::negate(Condition cond) {
|
||||
|
||||
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;
|
||||
|
@ -52,7 +52,7 @@ ValueStack::ValueStack(ValueStack* copy_from, Kind kind, int bci)
|
||||
, _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());
|
||||
|
@ -75,7 +75,7 @@ class ValueStack: public CompilationResourceObj {
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -136,6 +136,11 @@ ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) {
|
||||
_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 @@ ciEnv::ciEnv(Arena* arena) {
|
||||
_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 @@ void ciEnv::cache_jvmti_state() {
|
||||
_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 @@ void ciEnv::register_method(ciMethod* target,
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ private:
|
||||
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 @@ public:
|
||||
|
||||
// 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
|
||||
|
@ -412,7 +412,7 @@ MethodLivenessResult ciMethod::raw_liveness_at_bci(int bci) {
|
||||
// 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);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
|
||||
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.
|
||||
|
@ -863,7 +863,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user