8214352: C1: Unnecessary "compilation bailout: block join failed" with JVMTI
authormdoerr
Fri, 14 Dec 2018 09:59:08 +0100
changeset 53028 b3830528df29
parent 53027 93b401e5bf51
child 53029 8180809085a4
8214352: C1: Unnecessary "compilation bailout: block join failed" with JVMTI Summary: Invalidate Phi functions for conflicting types and avoid bailout. Reviewed-by: kvn, iveresov
src/hotspot/share/c1/c1_Instruction.cpp
src/hotspot/share/c1/c1_LIRGenerator.cpp
src/hotspot/share/c1/c1_LinearScan.cpp
src/hotspot/share/c1/c1_ValueStack.hpp
--- a/src/hotspot/share/c1/c1_Instruction.cpp	Fri Dec 14 01:34:13 2018 +0100
+++ b/src/hotspot/share/c1/c1_Instruction.cpp	Fri Dec 14 09:59:08 2018 +0100
@@ -827,9 +827,16 @@
       for_each_local_value(existing_state, index, existing_value) {
         Value new_value = new_state->local_at(index);
         if (new_value == NULL || new_value->type()->tag() != existing_value->type()->tag()) {
-          // The old code invalidated the phi function here
-          // Because dead locals are replaced with NULL, this is a very rare case now, so simply bail out
-          return false; // BAILOUT in caller
+          Phi* existing_phi = existing_value->as_Phi();
+          if (existing_phi == NULL) {
+            return false; // BAILOUT in caller
+          }
+          // Invalidate the phi function here. This case is very rare except for
+          // JVMTI capability "can_access_local_variables".
+          // In really rare cases we will bail out in LIRGenerator::move_to_phi.
+          existing_phi->make_illegal();
+          existing_state->invalidate_local(index);
+          TRACE_PHI(tty->print_cr("invalidating local %d because of type mismatch", index));
         }
       }
 
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp	Fri Dec 14 01:34:13 2018 +0100
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp	Fri Dec 14 09:59:08 2018 +0100
@@ -1113,7 +1113,7 @@
   // no moves are created for phi functions at the begin of exception
   // handlers, so assign operands manually here
   for_each_phi_fun(block(), phi,
-                   operand_for_instruction(phi));
+                   if (!phi->is_illegal()) { operand_for_instruction(phi); });
 
   LIR_Opr thread_reg = getThreadPointer();
   __ move_wide(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT),
--- a/src/hotspot/share/c1/c1_LinearScan.cpp	Fri Dec 14 01:34:13 2018 +0100
+++ b/src/hotspot/share/c1/c1_LinearScan.cpp	Fri Dec 14 09:59:08 2018 +0100
@@ -574,7 +574,7 @@
       // Phi functions at the begin of an exception handler are
       // implicitly defined (= killed) at the beginning of the block.
       for_each_phi_fun(block, phi,
-        live_kill.set_bit(phi->operand()->vreg_number())
+        if (!phi->is_illegal()) { live_kill.set_bit(phi->operand()->vreg_number()); }
       );
     }
 
@@ -1904,7 +1904,7 @@
 
   // the live_in bits are not set for phi functions of the xhandler entry, so iterate them separately
   for_each_phi_fun(block, phi,
-    resolve_exception_entry(block, phi->operand()->vreg_number(), move_resolver)
+    if (!phi->is_illegal()) { resolve_exception_entry(block, phi->operand()->vreg_number(), move_resolver); }
   );
 
   if (move_resolver.has_mappings()) {
@@ -1978,7 +1978,7 @@
 
   // the live_in bits are not set for phi functions of the xhandler entry, so iterate them separately
   for_each_phi_fun(block, phi,
-    resolve_exception_edge(handler, throwing_op_id, phi->operand()->vreg_number(), phi, move_resolver)
+    if (!phi->is_illegal()) { resolve_exception_edge(handler, throwing_op_id, phi->operand()->vreg_number(), phi, move_resolver); }
   );
 
   if (move_resolver.has_mappings()) {
--- a/src/hotspot/share/c1/c1_ValueStack.hpp	Fri Dec 14 01:34:13 2018 +0100
+++ b/src/hotspot/share/c1/c1_ValueStack.hpp	Fri Dec 14 09:59:08 2018 +0100
@@ -299,7 +299,7 @@
 }
 
 
-// Macro definition for simple iteration of all phif functions of a block, i.e all
+// Macro definition for simple iteration of all phi functions of a block, i.e all
 // phi functions of the ValueStack where the block matches.
 // Use the following code pattern to iterate all phi functions of a block:
 //
@@ -315,7 +315,7 @@
   Value value;                                                                                 \
   {                                                                                            \
     for_each_stack_value(cur_state, cur_index, value) {                                        \
-      Phi* v_phi = value->as_Phi();                                                      \
+      Phi* v_phi = value->as_Phi();                                                            \
       if (v_phi != NULL && v_phi->block() == v_block) {                                        \
         v_code;                                                                                \
       }                                                                                        \
@@ -323,7 +323,7 @@
   }                                                                                            \
   {                                                                                            \
     for_each_local_value(cur_state, cur_index, value) {                                        \
-      Phi* v_phi = value->as_Phi();                                                      \
+      Phi* v_phi = value->as_Phi();                                                            \
       if (v_phi != NULL && v_phi->block() == v_block) {                                        \
         v_code;                                                                                \
       }                                                                                        \