8194988: 8 Null pointer dereference defect groups related to MultiNode::proj_out()
Reviewed-by: kvn
--- a/src/hotspot/share/opto/callnode.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/callnode.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -772,7 +772,7 @@
ciKlass* boxing_klass = t_oop->klass();
if (is_CallStaticJava() && as_CallStaticJava()->is_boxing_method()) {
// Skip unrelated boxing methods.
- Node* proj = proj_out(TypeFunc::Parms);
+ Node* proj = proj_out_or_null(TypeFunc::Parms);
if ((proj == NULL) || (phase->type(proj)->is_instptr()->klass() != boxing_klass)) {
return false;
}
@@ -784,7 +784,7 @@
}
// May modify (by reflection) if an boxing object is passed
// as argument or returned.
- Node* proj = returns_pointer() ? proj_out(TypeFunc::Parms) : NULL;
+ Node* proj = returns_pointer() ? proj_out_or_null(TypeFunc::Parms) : NULL;
if (proj != NULL) {
const TypeInstPtr* inst_t = phase->type(proj)->isa_instptr();
if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
@@ -824,7 +824,7 @@
Node *CallNode::result_cast() {
Node *cast = NULL;
- Node *p = proj_out(TypeFunc::Parms);
+ Node *p = proj_out_or_null(TypeFunc::Parms);
if (p == NULL)
return NULL;
@@ -1378,13 +1378,13 @@
PhaseIterGVN *igvn = phase->is_IterGVN();
// Unreachable fall through path (negative array length),
// the allocation can only throw so disconnect it.
- Node* proj = proj_out(TypeFunc::Control);
+ Node* proj = proj_out_or_null(TypeFunc::Control);
Node* catchproj = NULL;
if (proj != NULL) {
for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) {
Node *cn = proj->fast_out(i);
if (cn->is_Catch()) {
- catchproj = cn->as_Multi()->proj_out(CatchProjNode::fall_through_index);
+ catchproj = cn->as_Multi()->proj_out_or_null(CatchProjNode::fall_through_index);
break;
}
}
@@ -1442,7 +1442,7 @@
// Create a cast which is control dependent on the initialization to
// propagate the fact that the array length must be positive.
length = new CastIINode(length, narrow_length_type);
- length->set_req(0, initialization()->proj_out(0));
+ length->set_req(0, initialization()->proj_out_or_null(0));
}
}
--- a/src/hotspot/share/opto/cfgnode.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/cfgnode.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2373,7 +2373,7 @@
if (can_reshape && !in(0)->is_Loop()) {
// Dead code elimination can sometimes delete this projection so
// if it's not there, there's nothing to do.
- Node* fallthru = proj_out(0);
+ Node* fallthru = proj_out_or_null(0);
if (fallthru != NULL) {
phase->is_IterGVN()->replace_node(fallthru, in(0));
}
--- a/src/hotspot/share/opto/divnode.hpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/divnode.hpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -154,8 +154,8 @@
virtual bool is_CFG() const { return false; }
virtual uint ideal_reg() const { return NotAMachineReg; }
- ProjNode* div_proj() { return proj_out(div_proj_num); }
- ProjNode* mod_proj() { return proj_out(mod_proj_num); }
+ ProjNode* div_proj() { return proj_out_or_null(div_proj_num); }
+ ProjNode* mod_proj() { return proj_out_or_null(mod_proj_num); }
};
//------------------------------DivModINode---------------------------------------
--- a/src/hotspot/share/opto/escape.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/escape.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -366,7 +366,7 @@
delayed_worklist->push(n);
// Check if a call returns an object.
if ((n->as_Call()->returns_pointer() &&
- n->as_Call()->proj_out(TypeFunc::Parms) != NULL) ||
+ n->as_Call()->proj_out_or_null(TypeFunc::Parms) != NULL) ||
(n->is_CallStaticJava() &&
n->as_CallStaticJava()->is_boxing_method())) {
add_call_node(n->as_Call());
@@ -2674,7 +2674,7 @@
PhaseGVN* igvn = _igvn;
const TypeOopPtr *toop = C->get_adr_type(alias_idx)->isa_oopptr();
bool is_instance = (toop != NULL) && toop->is_known_instance();
- Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
+ Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
Node *prev = NULL;
Node *result = orig_mem;
while (prev != result) {
@@ -3028,7 +3028,7 @@
// An allocation may have an Initialize which has raw stores. Scan
// the users of the raw allocation result and push AddP users
// on alloc_worklist.
- Node *raw_result = alloc->proj_out(TypeFunc::Parms);
+ Node *raw_result = alloc->proj_out_or_null(TypeFunc::Parms);
assert (raw_result != NULL, "must have an allocation result");
for (DUIterator_Fast imax, i = raw_result->fast_outs(imax); i < imax; i++) {
Node *use = raw_result->fast_out(i);
@@ -3219,7 +3219,7 @@
// we don't need to do anything, but the users must be pushed
} else if (n->is_MemBar()) { // Initialize, MemBar nodes
// we don't need to do anything, but the users must be pushed
- n = n->as_MemBar()->proj_out(TypeFunc::Memory);
+ n = n->as_MemBar()->proj_out_or_null(TypeFunc::Memory);
if (n == NULL)
continue;
} else if (n->Opcode() == Op_StrCompressedCopy ||
--- a/src/hotspot/share/opto/graphKit.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/graphKit.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3754,7 +3754,7 @@
// Trace Allocate -> Proj[Parm] -> Initialize
InitializeNode* AllocateNode::initialization() {
- ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
+ ProjNode* rawoop = proj_out_or_null(AllocateNode::RawAddress);
if (rawoop == NULL) return NULL;
for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
Node* init = rawoop->fast_out(i);
--- a/src/hotspot/share/opto/ifnode.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/ifnode.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -505,7 +505,7 @@
// Flip 1: If (Bool[<] CmpU(l, LoadRange)) ...
// Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ...
- ProjNode* iftrap = proj_out(flip_test == 2 ? true : false);
+ ProjNode* iftrap = proj_out_or_null(flip_test == 2 ? true : false);
return iftrap;
}
@@ -1471,7 +1471,7 @@
// be skipped. For example, range check predicate has two checks
// for lower and upper bounds.
ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj();
- if ((unc_proj != NULL) && (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) != NULL)) {
+ if (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) != NULL) {
prev_dom = idom;
}
--- a/src/hotspot/share/opto/library_call.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/library_call.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1495,7 +1495,7 @@
// escape analysis can go from the MemBarStoreStoreNode to the
// AllocateNode and eliminate the MemBarStoreStoreNode if possible
// based on the escape status of the AllocateNode.
- insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress));
}
if (compress) {
set_result(_gvn.transform(count));
@@ -1589,7 +1589,7 @@
// escape analysis can go from the MemBarStoreStoreNode to the
// AllocateNode and eliminate the MemBarStoreStoreNode if possible
// based on the escape status of the AllocateNode.
- insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress));
} else {
insert_mem_bar(Op_MemBarCPUOrder);
}
@@ -1675,7 +1675,7 @@
// escape analysis can go from the MemBarStoreStoreNode to the
// AllocateNode and eliminate the MemBarStoreStoreNode if possible
// based on the escape status of the AllocateNode.
- insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress));
} else {
insert_mem_bar(Op_MemBarCPUOrder);
}
@@ -4722,7 +4722,7 @@
// escape analysis can go from the MemBarStoreStoreNode to the
// AllocateNode and eliminate the MemBarStoreStoreNode if possible
// based on the escape status of the AllocateNode.
- insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress));
} else {
insert_mem_bar(Op_MemBarCPUOrder);
}
@@ -5031,7 +5031,7 @@
Node *mem = reset_memory();
set_all_memory(mem);
alloc->set_req(TypeFunc::Memory, mem);
- set_control(init->proj_out(TypeFunc::Control));
+ set_control(init->proj_out_or_null(TypeFunc::Control));
set_i_o(callprojs.fallthrough_ioproj);
// Update memory as done in GraphKit::set_output_for_allocation()
@@ -5042,8 +5042,8 @@
}
const TypePtr* telemref = ary_type->add_offset(Type::OffsetBot);
int elemidx = C->get_alias_index(telemref);
- set_memory(init->proj_out(TypeFunc::Memory), Compile::AliasIdxRaw);
- set_memory(init->proj_out(TypeFunc::Memory), elemidx);
+ set_memory(init->proj_out_or_null(TypeFunc::Memory), Compile::AliasIdxRaw);
+ set_memory(init->proj_out_or_null(TypeFunc::Memory), elemidx);
Node* allocx = _gvn.transform(alloc);
assert(allocx == alloc, "where has the allocation gone?");
@@ -5360,7 +5360,7 @@
// to finish initializing the allocated object.
if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) {
IfNode* iff = ctl->in(0)->as_If();
- Node* not_ctl = iff->proj_out(1 - ctl->as_Proj()->_con);
+ Node* not_ctl = iff->proj_out_or_null(1 - ctl->as_Proj()->_con);
assert(not_ctl != NULL && not_ctl != ctl, "found alternate");
if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) {
ctl = iff->in(0); // This test feeds the known slow_region.
--- a/src/hotspot/share/opto/loopTransform.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/loopTransform.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3204,7 +3204,7 @@
return false;
}
- Node* exit = head->loopexit()->proj_out(0);
+ Node* exit = head->loopexit()->proj_out_or_null(0);
if (exit == NULL) {
return false;
}
@@ -3280,8 +3280,8 @@
call->init_req(TypeFunc::Control, head->init_control());
call->init_req(TypeFunc::I_O, C->top()); // Does no I/O.
call->init_req(TypeFunc::Memory, mem_phi->in(LoopNode::EntryControl));
- call->init_req(TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr));
- call->init_req(TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr));
+ call->init_req(TypeFunc::ReturnAdr, C->start()->proj_out_or_null(TypeFunc::ReturnAdr));
+ call->init_req(TypeFunc::FramePtr, C->start()->proj_out_or_null(TypeFunc::FramePtr));
_igvn.register_new_node_with_optimizer(call);
result_ctrl = new ProjNode(call,TypeFunc::Control);
_igvn.register_new_node_with_optimizer(result_ctrl);
--- a/src/hotspot/share/opto/loopnode.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/loopnode.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -70,9 +70,9 @@
CountedLoopNode* l = as_CountedLoop();
CountedLoopEndNode* le = l->loopexit();
if (le != NULL &&
- le->proj_out(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
+ le->proj_out_or_null(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
Node* phi = l->phi();
- Node* exit = le->proj_out(0 /* false */);
+ Node* exit = le->proj_out_or_null(0 /* false */);
if (exit != NULL && exit->Opcode() == Op_IfFalse &&
phi != NULL && phi->is_Phi() &&
phi->in(LoopNode::LoopBackControl) == l->incr() &&
@@ -1216,7 +1216,7 @@
if (le == NULL) {
return NULL;
}
- Node* c = le->proj_out(false);
+ Node* c = le->proj_out_or_null(false);
if (c == NULL) {
return NULL;
}
--- a/src/hotspot/share/opto/loopopts.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/loopopts.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -239,7 +239,7 @@
// Make control-dependent data Nodes on the live path (path that will remain
// once the dominated IF is removed) become control-dependent on the
// dominating projection.
- Node* dp = iff->as_If()->proj_out(pop == Op_IfTrue);
+ Node* dp = iff->as_If()->proj_out_or_null(pop == Op_IfTrue);
// Loop predicates may have depending checks which should not
// be skipped. For example, range check predicate has two checks
@@ -1956,7 +1956,7 @@
if (head->is_strip_mined() && mode != IgnoreStripMined) {
CountedLoopNode* cl = head->as_CountedLoop();
CountedLoopEndNode* cle = cl->loopexit();
- Node* cle_out = cle->proj_out(false);
+ Node* cle_out = cle->proj_out_or_null(false);
if (use == cle_out) {
IfNode* le = cl->outer_loop_end();
use = le->proj_out(false);
--- a/src/hotspot/share/opto/macro.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/macro.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -496,7 +496,7 @@
if (level <= 0) {
return NULL; // Give up: phi tree too deep
}
- Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
+ Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
Node *alloc_mem = alloc->in(TypeFunc::Memory);
uint length = mem->req();
@@ -576,7 +576,7 @@
int alias_idx = C->get_alias_index(adr_t);
int offset = adr_t->offset();
- Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
+ Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
Node *alloc_ctrl = alloc->in(TypeFunc::Control);
Node *alloc_mem = alloc->in(TypeFunc::Memory);
Arena *a = Thread::current()->resource_area();
@@ -974,8 +974,8 @@
}
static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) {
- Node* ctl_proj = n->proj_out(TypeFunc::Control);
- Node* mem_proj = n->proj_out(TypeFunc::Memory);
+ Node* ctl_proj = n->proj_out_or_null(TypeFunc::Control);
+ Node* mem_proj = n->proj_out_or_null(TypeFunc::Memory);
if (ctl_proj != NULL) {
igvn.replace_node(ctl_proj, n->in(0));
}
@@ -1086,12 +1086,12 @@
// Eliminate Initialize node.
InitializeNode *init = use->as_Initialize();
assert(init->outcnt() <= 2, "only a control and memory projection expected");
- Node *ctrl_proj = init->proj_out(TypeFunc::Control);
+ Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
if (ctrl_proj != NULL) {
assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
_igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
}
- Node *mem_proj = init->proj_out(TypeFunc::Memory);
+ Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
if (mem_proj != NULL) {
Node *mem = init->in(TypeFunc::Memory);
#ifdef ASSERT
@@ -1198,7 +1198,7 @@
bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
// EA should remove all uses of non-escaping boxing node.
- if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) {
+ if (!C->eliminate_boxing() || boxing->proj_out_or_null(TypeFunc::Parms) != NULL) {
return false;
}
@@ -1580,8 +1580,8 @@
// before the InitializeNode happen before the storestore
// barrier.
- Node* init_ctrl = init->proj_out(TypeFunc::Control);
- Node* init_mem = init->proj_out(TypeFunc::Memory);
+ Node* init_ctrl = init->proj_out_or_null(TypeFunc::Control);
+ Node* init_mem = init->proj_out_or_null(TypeFunc::Memory);
MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
transform_later(mb);
--- a/src/hotspot/share/opto/memnode.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/memnode.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -136,7 +136,7 @@
if (!(is_instance || is_boxed_value_load))
return mchain; // don't try to optimize non-instance types
uint instance_id = t_oop->instance_id();
- Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
+ Node *start_mem = phase->C->start()->proj_out_or_null(TypeFunc::Memory);
Node *prev = NULL;
Node *result = mchain;
while (prev != result) {
--- a/src/hotspot/share/opto/multnode.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/multnode.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,8 @@
Node *MultiNode::match( const ProjNode *proj, const Matcher *m ) { return proj->clone(); }
//------------------------------proj_out---------------------------------------
-// Get a named projection
-ProjNode* MultiNode::proj_out(uint which_proj) const {
+// Get a named projection or null if not found
+ProjNode* MultiNode::proj_out_or_null(uint which_proj) const {
assert((Opcode() != Op_If && Opcode() != Op_RangeCheck) || which_proj == (uint)true || which_proj == (uint)false, "must be 1 or 0");
assert((Opcode() != Op_If && Opcode() != Op_RangeCheck) || outcnt() == 2, "bad if #1");
for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
@@ -63,6 +63,13 @@
return NULL;
}
+// Get a named projection
+ProjNode* MultiNode::proj_out(uint which_proj) const {
+ ProjNode* p = proj_out_or_null(which_proj);
+ assert(p != NULL, "named projection %u not found", which_proj);
+ return p;
+}
+
//=============================================================================
//------------------------------ProjNode---------------------------------------
uint ProjNode::hash() const {
@@ -214,8 +221,6 @@
}
ProjNode* other_proj = iff->proj_out(1-_con);
- if (other_proj == NULL) // Should never happen, but make Parfait happy.
- return NULL;
CallStaticJavaNode* call = other_proj->is_uncommon_trap_proj(reason);
if (call != NULL) {
assert(reason == Deoptimization::Reason_none ||
--- a/src/hotspot/share/opto/multnode.hpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/multnode.hpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
virtual Node *match( const ProjNode *proj, const Matcher *m );
virtual uint ideal_reg() const { return NotAMachineReg; }
ProjNode* proj_out(uint which_proj) const; // Get a named projection
+ ProjNode* proj_out_or_null(uint which_proj) const;
};
--- a/src/hotspot/share/opto/phaseX.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/phaseX.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1524,7 +1524,7 @@
// receiver to know when to enable the regular fall-through path
// in addition to the NullPtrException path.
if (use->is_CallDynamicJava() && n == use->in(TypeFunc::Parms)) {
- Node* p = use->as_CallDynamicJava()->proj_out(TypeFunc::Control);
+ Node* p = use->as_CallDynamicJava()->proj_out_or_null(TypeFunc::Control);
if (p != NULL) {
add_users_to_worklist0(p);
}
@@ -1617,12 +1617,12 @@
if (use_op == Op_Allocate || use_op == Op_AllocateArray) {
InitializeNode* init = use->as_Allocate()->initialization();
if (init != NULL) {
- Node* imem = init->proj_out(TypeFunc::Memory);
+ Node* imem = init->proj_out_or_null(TypeFunc::Memory);
if (imem != NULL) add_users_to_worklist0(imem);
}
}
if (use_op == Op_Initialize) {
- Node* imem = use->as_Initialize()->proj_out(TypeFunc::Memory);
+ Node* imem = use->as_Initialize()->proj_out_or_null(TypeFunc::Memory);
if (imem != NULL) add_users_to_worklist0(imem);
}
// Loading the java mirror from a klass oop requires two loads and the type
--- a/src/hotspot/share/opto/stringopts.cpp Wed Jan 17 22:44:40 2018 +0100
+++ b/src/hotspot/share/opto/stringopts.cpp Wed Jan 17 14:25:47 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -362,11 +362,11 @@
// Eliminate Initialize node.
assert(init->outcnt() <= 2, "only a control and memory projection expected");
assert(init->req() <= InitializeNode::RawStores, "no pending inits");
- Node *ctrl_proj = init->proj_out(TypeFunc::Control);
+ Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
if (ctrl_proj != NULL) {
C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
}
- Node *mem_proj = init->proj_out(TypeFunc::Memory);
+ Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
if (mem_proj != NULL) {
Node *mem = init->in(TypeFunc::Memory);
C->gvn_replace_by(mem_proj, mem);
@@ -891,7 +891,7 @@
ctrl_path.push(cn);
ctrl_path.push(cn->proj_out(0));
ctrl_path.push(cn->proj_out(0)->unique_out());
- Node* catchproj = cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0);
+ Node* catchproj = cn->proj_out(0)->unique_out()->as_Catch()->proj_out_or_null(0);
if (catchproj != NULL) {
ctrl_path.push(catchproj);
}
@@ -1035,13 +1035,13 @@
// by calls in the region.
_stringopts->_visited.Clear();
Node_List worklist;
- Node* final_result = _end->proj_out(TypeFunc::Parms);
+ Node* final_result = _end->proj_out_or_null(TypeFunc::Parms);
for (uint i = 0; i < _control.size(); i++) {
CallNode* cnode = _control.at(i)->isa_Call();
if (cnode != NULL) {
_stringopts->_visited.test_set(cnode->_idx);
}
- Node* result = cnode != NULL ? cnode->proj_out(TypeFunc::Parms) : NULL;
+ Node* result = cnode != NULL ? cnode->proj_out_or_null(TypeFunc::Parms) : NULL;
if (result != NULL && result != final_result) {
worklist.push(result);
}