8225653: Provide more information when hitting SIGILL from HaltNode
Add information string for each HaltNode which is printed if hit at runtime. Reviewed-by: vlivanov, thartmann
This commit is contained in:
parent
51b0eab330
commit
2c3973af9b
@ -2097,7 +2097,7 @@ instruct ShouldNotReachHere() %{
|
|||||||
match(Halt);
|
match(Halt);
|
||||||
format %{ "ud2\t# ShouldNotReachHere" %}
|
format %{ "ud2\t# ShouldNotReachHere" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ ud2();
|
__ stop(_halt_reason);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
@ -252,6 +252,7 @@ int main(int argc, char *argv[])
|
|||||||
AD.addInclude(AD._CPP_GEN_file, "adfiles", get_basename(AD._HPP_file._name));
|
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/cfgnode.hpp");
|
||||||
AD.addInclude(AD._CPP_GEN_file, "opto/locknode.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, "precompiled.hpp");
|
||||||
AD.addInclude(AD._CPP_MISC_file, "adfiles", get_basename(AD._HPP_file._name));
|
AD.addInclude(AD._CPP_MISC_file, "adfiles", get_basename(AD._HPP_file._name));
|
||||||
AD.addInclude(AD._CPP_PEEPHOLE_file, "precompiled.hpp");
|
AD.addInclude(AD._CPP_PEEPHOLE_file, "precompiled.hpp");
|
||||||
|
@ -3937,6 +3937,9 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
|
|||||||
fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
|
fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
|
||||||
fprintf(fp_cpp, "%s node->_fcnt = _leaf->as_If()->_fcnt;\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()) {
|
if (inst->is_ideal_jump()) {
|
||||||
fprintf(fp_cpp, "%s node->_probs = _leaf->as_Jump()->_probs;\n", indent);
|
fprintf(fp_cpp, "%s node->_probs = _leaf->as_Jump()->_probs;\n", indent);
|
||||||
}
|
}
|
||||||
|
@ -1431,7 +1431,7 @@ Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||||||
Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr );
|
Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr );
|
||||||
frame = phase->transform(frame);
|
frame = phase->transform(frame);
|
||||||
// Halt & Catch Fire
|
// 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->C->root()->add_req(halt);
|
||||||
phase->transform(halt);
|
phase->transform(halt);
|
||||||
|
|
||||||
|
@ -1412,7 +1412,7 @@ Node* GraphKit::must_be_not_null(Node* value, bool do_replace_in_map) {
|
|||||||
_gvn.set_type(iff, iff->Value(&_gvn));
|
_gvn.set_type(iff, iff->Value(&_gvn));
|
||||||
Node *if_f = _gvn.transform(new IfFalseNode(iff));
|
Node *if_f = _gvn.transform(new IfFalseNode(iff));
|
||||||
Node *frame = _gvn.transform(new ParmNode(C->start(), TypeFunc::FramePtr));
|
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);
|
C->root()->add_req(halt);
|
||||||
Node *if_t = _gvn.transform(new IfTrueNode(iff));
|
Node *if_t = _gvn.transform(new IfTrueNode(iff));
|
||||||
set_control(if_t);
|
set_control(if_t);
|
||||||
@ -2116,7 +2116,7 @@ void GraphKit::uncommon_trap(int trap_request,
|
|||||||
// The debug info is the only real input to this call.
|
// The debug info is the only real input to this call.
|
||||||
|
|
||||||
// Halt-and-catch fire here. The above call should never return!
|
// 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);
|
_gvn.set_type_bottom(halt);
|
||||||
root()->add_req(halt);
|
root()->add_req(halt);
|
||||||
|
|
||||||
|
@ -1293,7 +1293,7 @@ Node* PhaseIdealLoop::clone_skeleton_predicate(Node* iff, Node* value, Node* pre
|
|||||||
Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
|
Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
|
||||||
register_new_node(frame, C->start());
|
register_new_node(frame, C->start());
|
||||||
// It's impossible for the predicate to fail at runtime. Use an Halt node.
|
// 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);
|
C->root()->add_req(halt);
|
||||||
new_iff->set_req(0, prev_proj);
|
new_iff->set_req(0, prev_proj);
|
||||||
|
|
||||||
@ -2455,7 +2455,7 @@ Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoop
|
|||||||
register_control(iftrue, loop->_parent, new_iff);
|
register_control(iftrue, loop->_parent, new_iff);
|
||||||
Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
|
Node *frame = new ParmNode(C->start(), TypeFunc::FramePtr);
|
||||||
register_new_node(frame, C->start());
|
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);
|
register_control(halt, _ltree_root, iffalse);
|
||||||
C->root()->add_req(halt);
|
C->root()->add_req(halt);
|
||||||
return iftrue;
|
return iftrue;
|
||||||
|
@ -3651,7 +3651,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
|
|||||||
Node *frame = new ParmNode( C->start(), TypeFunc::FramePtr );
|
Node *frame = new ParmNode( C->start(), TypeFunc::FramePtr );
|
||||||
_igvn.register_new_node_with_optimizer(frame);
|
_igvn.register_new_node_with_optimizer(frame);
|
||||||
// Halt & Catch Fire
|
// 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);
|
_igvn.register_new_node_with_optimizer(halt);
|
||||||
set_loop(halt, l);
|
set_loop(halt, l);
|
||||||
C->root()->add_req(halt);
|
C->root()->add_req(halt);
|
||||||
|
@ -1004,6 +1004,7 @@ public:
|
|||||||
// Machine-specific versions of halt nodes
|
// Machine-specific versions of halt nodes
|
||||||
class MachHaltNode : public MachReturnNode {
|
class MachHaltNode : public MachReturnNode {
|
||||||
public:
|
public:
|
||||||
|
const char* _halt_reason;
|
||||||
virtual JVMState* jvms() const;
|
virtual JVMState* jvms() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node* frame = igvn->transform(new ParmNode(phase->C->start(), TypeFunc::FramePtr));
|
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);
|
phase->C->root()->add_req(halt);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ class EncodePNode;
|
|||||||
class EncodePKlassNode;
|
class EncodePKlassNode;
|
||||||
class FastLockNode;
|
class FastLockNode;
|
||||||
class FastUnlockNode;
|
class FastUnlockNode;
|
||||||
|
class HaltNode;
|
||||||
class IfNode;
|
class IfNode;
|
||||||
class IfProjNode;
|
class IfProjNode;
|
||||||
class IfFalseNode;
|
class IfFalseNode;
|
||||||
@ -717,8 +718,9 @@ public:
|
|||||||
DEFINE_CLASS_ID(Mul, Node, 12)
|
DEFINE_CLASS_ID(Mul, Node, 12)
|
||||||
DEFINE_CLASS_ID(Vector, Node, 13)
|
DEFINE_CLASS_ID(Vector, Node, 13)
|
||||||
DEFINE_CLASS_ID(ClearArray, Node, 14)
|
DEFINE_CLASS_ID(ClearArray, Node, 14)
|
||||||
|
DEFINE_CLASS_ID(Halt, Node, 15)
|
||||||
|
|
||||||
_max_classes = ClassMask_ClearArray
|
_max_classes = ClassMask_Halt
|
||||||
};
|
};
|
||||||
#undef DEFINE_CLASS_ID
|
#undef DEFINE_CLASS_ID
|
||||||
|
|
||||||
@ -749,7 +751,6 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
// These methods should be called from constructors only.
|
// These methods should be called from constructors only.
|
||||||
void init_class_id(jushort c) {
|
void init_class_id(jushort c) {
|
||||||
assert(c <= _max_classes, "invalid node class");
|
|
||||||
_class_id = c; // cast out const
|
_class_id = c; // cast out const
|
||||||
}
|
}
|
||||||
void init_flags(jushort fl) {
|
void init_flags(jushort fl) {
|
||||||
@ -822,6 +823,7 @@ public:
|
|||||||
DEFINE_CLASS_QUERY(EncodePKlass)
|
DEFINE_CLASS_QUERY(EncodePKlass)
|
||||||
DEFINE_CLASS_QUERY(FastLock)
|
DEFINE_CLASS_QUERY(FastLock)
|
||||||
DEFINE_CLASS_QUERY(FastUnlock)
|
DEFINE_CLASS_QUERY(FastUnlock)
|
||||||
|
DEFINE_CLASS_QUERY(Halt)
|
||||||
DEFINE_CLASS_QUERY(If)
|
DEFINE_CLASS_QUERY(If)
|
||||||
DEFINE_CLASS_QUERY(RangeCheck)
|
DEFINE_CLASS_QUERY(RangeCheck)
|
||||||
DEFINE_CLASS_QUERY(IfProj)
|
DEFINE_CLASS_QUERY(IfProj)
|
||||||
|
@ -62,7 +62,8 @@ Node *RootNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
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();
|
Node* top = Compile::current()->top();
|
||||||
init_req(TypeFunc::Control, ctrl );
|
init_req(TypeFunc::Control, ctrl );
|
||||||
init_req(TypeFunc::I_O, top);
|
init_req(TypeFunc::I_O, top);
|
||||||
|
@ -51,7 +51,8 @@ public:
|
|||||||
// Throw an exception & die
|
// Throw an exception & die
|
||||||
class HaltNode : public Node {
|
class HaltNode : public Node {
|
||||||
public:
|
public:
|
||||||
HaltNode( Node *ctrl, Node *frameptr );
|
const char* _halt_reason;
|
||||||
|
HaltNode(Node* ctrl, Node* frameptr, const char* halt_reason);
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
virtual bool pinned() const { return true; };
|
virtual bool pinned() const { return true; };
|
||||||
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user