8225653: Provide more information when hitting SIGILL from HaltNode
authorchagedorn
Tue, 10 Sep 2019 08:43:33 +0200
changeset 58061 fafba5cf3546
parent 58060 44f3609f46af
child 58062 65cad575ace3
8225653: Provide more information when hitting SIGILL from HaltNode Summary: Add information string for each HaltNode which is printed if hit at runtime. Reviewed-by: vlivanov, thartmann
src/hotspot/cpu/x86/x86.ad
src/hotspot/share/adlc/main.cpp
src/hotspot/share/adlc/output_c.cpp
src/hotspot/share/opto/callnode.cpp
src/hotspot/share/opto/graphKit.cpp
src/hotspot/share/opto/loopTransform.cpp
src/hotspot/share/opto/loopnode.cpp
src/hotspot/share/opto/machnode.hpp
src/hotspot/share/opto/memnode.cpp
src/hotspot/share/opto/node.hpp
src/hotspot/share/opto/rootnode.cpp
src/hotspot/share/opto/rootnode.hpp
--- a/src/hotspot/cpu/x86/x86.ad	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/cpu/x86/x86.ad	Tue Sep 10 08:43:33 2019 +0200
@@ -2097,7 +2097,7 @@
   match(Halt);
   format %{ "ud2\t# ShouldNotReachHere" %}
   ins_encode %{
-    __ ud2();
+    __ stop(_halt_reason);
   %}
   ins_pipe(pipe_slow);
 %}
--- a/src/hotspot/share/adlc/main.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/adlc/main.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -252,6 +252,7 @@
   AD.addInclude(AD._CPP_GEN_file, "adfiles", get_basename(AD._HPP_file._name));
   AD.addInclude(AD._CPP_GEN_file, "opto/cfgnode.hpp");
   AD.addInclude(AD._CPP_GEN_file, "opto/locknode.hpp");
+  AD.addInclude(AD._CPP_GEN_file, "opto/rootnode.hpp");
   AD.addInclude(AD._CPP_MISC_file, "precompiled.hpp");
   AD.addInclude(AD._CPP_MISC_file, "adfiles", get_basename(AD._HPP_file._name));
   AD.addInclude(AD._CPP_PEEPHOLE_file, "precompiled.hpp");
--- a/src/hotspot/share/adlc/output_c.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/adlc/output_c.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -3937,6 +3937,9 @@
     fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
     fprintf(fp_cpp, "%s node->_fcnt = _leaf->as_If()->_fcnt;\n", indent);
   }
+  if (inst->is_ideal_halt()) {
+    fprintf(fp_cpp, "%s node->_halt_reason = _leaf->as_Halt()->_halt_reason;\n", indent);
+  }
   if (inst->is_ideal_jump()) {
     fprintf(fp_cpp, "%s node->_probs = _leaf->as_Jump()->_probs;\n", indent);
   }
--- a/src/hotspot/share/opto/callnode.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/callnode.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -1431,7 +1431,7 @@
         Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr );
         frame = phase->transform(frame);
         // Halt & Catch Fire
-        Node *halt = new HaltNode( nproj, frame );
+        Node* halt = new HaltNode(nproj, frame, "unexpected negative array length");
         phase->C->root()->add_req(halt);
         phase->transform(halt);
 
--- a/src/hotspot/share/opto/graphKit.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/graphKit.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -1412,7 +1412,7 @@
   _gvn.set_type(iff, iff->Value(&_gvn));
   Node *if_f = _gvn.transform(new IfFalseNode(iff));
   Node *frame = _gvn.transform(new ParmNode(C->start(), TypeFunc::FramePtr));
-  Node *halt = _gvn.transform(new HaltNode(if_f, frame));
+  Node* halt = _gvn.transform(new HaltNode(if_f, frame, "unexpected null in intrinsic"));
   C->root()->add_req(halt);
   Node *if_t = _gvn.transform(new IfTrueNode(iff));
   set_control(if_t);
@@ -2116,7 +2116,7 @@
   // The debug info is the only real input to this call.
 
   // Halt-and-catch fire here.  The above call should never return!
-  HaltNode* halt = new HaltNode(control(), frameptr());
+  HaltNode* halt = new HaltNode(control(), frameptr(), "uncommon trap returned which should never happen");
   _gvn.set_type_bottom(halt);
   root()->add_req(halt);
 
--- a/src/hotspot/share/opto/loopTransform.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/loopTransform.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -1293,7 +1293,7 @@
   Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
   register_new_node(frame, C->start());
   // It's impossible for the predicate to fail at runtime. Use an Halt node.
-  Node* halt = new HaltNode(other_proj, frame);
+  Node* halt = new HaltNode(other_proj, frame, "duplicated predicate failed which is impossible");
   C->root()->add_req(halt);
   new_iff->set_req(0, prev_proj);
 
@@ -2455,7 +2455,7 @@
   register_control(iftrue, loop->_parent, new_iff);
   Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
   register_new_node(frame, C->start());
-  Node* halt = new HaltNode(iffalse, frame);
+  Node* halt = new HaltNode(iffalse, frame, "range check predicate failed which is impossible");
   register_control(halt, _ltree_root, iffalse);
   C->root()->add_req(halt);
   return iftrue;
--- a/src/hotspot/share/opto/loopnode.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/loopnode.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -3651,7 +3651,7 @@
           Node *frame = new ParmNode( C->start(), TypeFunc::FramePtr );
           _igvn.register_new_node_with_optimizer(frame);
           // Halt & Catch Fire
-          Node *halt = new HaltNode( if_f, frame );
+          Node* halt = new HaltNode(if_f, frame, "never-taken loop exit reached");
           _igvn.register_new_node_with_optimizer(halt);
           set_loop(halt, l);
           C->root()->add_req(halt);
--- a/src/hotspot/share/opto/machnode.hpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/machnode.hpp	Tue Sep 10 08:43:33 2019 +0200
@@ -1004,6 +1004,7 @@
 // Machine-specific versions of halt nodes
 class MachHaltNode : public MachReturnNode {
 public:
+  const char* _halt_reason;
   virtual JVMState* jvms() const;
 };
 
--- a/src/hotspot/share/opto/memnode.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/memnode.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -342,7 +342,7 @@
       }
     }
     Node* frame = igvn->transform(new ParmNode(phase->C->start(), TypeFunc::FramePtr));
-    Node* halt = igvn->transform(new HaltNode(ctl, frame));
+    Node* halt = igvn->transform(new HaltNode(ctl, frame, "unsafe off-heap access with zero address"));
     phase->C->root()->add_req(halt);
     return this;
   }
--- a/src/hotspot/share/opto/node.hpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/node.hpp	Tue Sep 10 08:43:33 2019 +0200
@@ -73,6 +73,7 @@
 class EncodePKlassNode;
 class FastLockNode;
 class FastUnlockNode;
+class HaltNode;
 class IfNode;
 class IfProjNode;
 class IfFalseNode;
@@ -717,8 +718,9 @@
     DEFINE_CLASS_ID(Mul,      Node, 12)
     DEFINE_CLASS_ID(Vector,   Node, 13)
     DEFINE_CLASS_ID(ClearArray, Node, 14)
+    DEFINE_CLASS_ID(Halt, Node, 15)
 
-    _max_classes  = ClassMask_ClearArray
+    _max_classes  = ClassMask_Halt
   };
   #undef DEFINE_CLASS_ID
 
@@ -749,7 +751,6 @@
 protected:
   // These methods should be called from constructors only.
   void init_class_id(jushort c) {
-    assert(c <= _max_classes, "invalid node class");
     _class_id = c; // cast out const
   }
   void init_flags(jushort fl) {
@@ -822,6 +823,7 @@
   DEFINE_CLASS_QUERY(EncodePKlass)
   DEFINE_CLASS_QUERY(FastLock)
   DEFINE_CLASS_QUERY(FastUnlock)
+  DEFINE_CLASS_QUERY(Halt)
   DEFINE_CLASS_QUERY(If)
   DEFINE_CLASS_QUERY(RangeCheck)
   DEFINE_CLASS_QUERY(IfProj)
--- a/src/hotspot/share/opto/rootnode.cpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/rootnode.cpp	Tue Sep 10 08:43:33 2019 +0200
@@ -62,7 +62,8 @@
 }
 
 //=============================================================================
-HaltNode::HaltNode( Node *ctrl, Node *frameptr ) : Node(TypeFunc::Parms) {
+HaltNode::HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason) : Node(TypeFunc::Parms), _halt_reason(halt_reason) {
+  init_class_id(Class_Halt);
   Node* top = Compile::current()->top();
   init_req(TypeFunc::Control,  ctrl        );
   init_req(TypeFunc::I_O,      top);
--- a/src/hotspot/share/opto/rootnode.hpp	Tue Sep 10 07:42:04 2019 +0200
+++ b/src/hotspot/share/opto/rootnode.hpp	Tue Sep 10 08:43:33 2019 +0200
@@ -51,7 +51,8 @@
 // Throw an exception & die
 class HaltNode : public Node {
 public:
-  HaltNode( Node *ctrl, Node *frameptr );
+  const char* _halt_reason;
+  HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason);
   virtual int Opcode() const;
   virtual bool  pinned() const { return true; };
   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);