8035493: JVMTI PopFrame capability must instruct compilers not to prune locals
authormgronlun
Sat, 22 Feb 2014 10:22:05 +0100
changeset 22893 e3a2b513713a
parent 22892 1709e0e0b87c
child 22894 870fbe165d06
8035493: JVMTI PopFrame capability must instruct compilers not to prune locals Reviewed-by: kvn, sla, coleenp, sspitsyn
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
hotspot/src/share/vm/c1/c1_Instruction.cpp
hotspot/src/share/vm/c1/c1_ValueStack.cpp
hotspot/src/share/vm/c1/c1_ValueStack.hpp
hotspot/src/share/vm/ci/ciEnv.cpp
hotspot/src/share/vm/ci/ciEnv.hpp
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/opto/c2compiler.cpp
hotspot/src/share/vm/opto/graphKit.cpp
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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);
--- a/hotspot/src/share/vm/c1/c1_Instruction.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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;
--- a/hotspot/src/share/vm/c1/c1_ValueStack.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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());
--- a/hotspot/src/share/vm/c1/c1_ValueStack.hpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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;
   }
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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");
     }
 
--- a/hotspot/src/share/vm/ci/ciEnv.hpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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);
   }
--- a/hotspot/src/share/vm/opto/c2compiler.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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.
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Thu Feb 20 16:38:45 2014 -0500
+++ b/hotspot/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