6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
authorkvn
Fri, 08 May 2009 10:44:20 -0700
changeset 2867 69187054225f
parent 2866 6beb2b47717a
child 2869 1c6ae49db9ec
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
hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
hotspot/src/share/vm/c1/c1_Compilation.cpp
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
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/compiler/compileBroker.cpp
hotspot/src/share/vm/opto/doCall.cpp
hotspot/src/share/vm/opto/graphKit.cpp
hotspot/src/share/vm/opto/macro.cpp
hotspot/src/share/vm/opto/parse1.cpp
hotspot/src/share/vm/opto/parse2.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();
   }
--- 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);
--- 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);
--- 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)));
   }
--- 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);
--- 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);
--- 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
--- 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());
 
--- 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; }
--- 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);
   }
--- 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);
--- 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;
   }
 
--- 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;
--- 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(),
--- 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();
--- 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,