8194988: 8 Null pointer dereference defect groups related to MultiNode::proj_out()

Reviewed-by: kvn
This commit is contained in:
Dean Long 2018-01-17 14:25:47 -08:00
parent 97a0bf821a
commit 4714dab4cb
16 changed files with 76 additions and 70 deletions

@ -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 @@ bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
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 @@ bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
}
// 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 @@ bool CallNode::has_non_debug_use(Node *n) {
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 @@ Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseTran
// 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));
}
}

@ -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 @@ Node *NeverBranchNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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));
}

@ -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 @@ public:
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---------------------------------------

@ -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 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
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 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
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 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
// 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 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
// 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 ||

@ -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 @@ AllocateNode* InitializeNode::allocation() {
// 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);

@ -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 @@ ProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) {
// 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 @@ Node* IfNode::dominated_by(Node* prev_dom, PhaseIterGVN *igvn) {
// 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;
}

@ -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 @@ bool LibraryCallKit::inline_string_copy(bool compress) {
// 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 @@ bool LibraryCallKit::inline_string_toBytesU() {
// 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 @@ bool LibraryCallKit::inline_string_getCharsU() {
// 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 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
// 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 @@ void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, No
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 @@ void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, No
}
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 @@ LibraryCallKit::tightly_coupled_allocation(Node* ptr,
// 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.

@ -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 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
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 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
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);

@ -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 @@ bool LoopNode::is_valid_counted_loop() const {
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 @@ IfFalseNode* OuterStripMinedLoopNode::outer_loop_exit() const {
if (le == NULL) {
return NULL;
}
Node* c = le->proj_out(false);
Node* c = le->proj_out_or_null(false);
if (c == NULL) {
return NULL;
}

@ -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 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exc
// 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 @@ void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd
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);

@ -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 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
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 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType
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 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
}
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 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
// 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_allocate_node(AllocateNode *alloc) {
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 @@ void PhaseMacroExpand::expand_allocate_common(
// 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);

@ -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 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oo
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) {

@ -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 @@ const RegMask &MultiNode::out_RegMask() const {
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 @@ ProjNode* MultiNode::proj_out(uint which_proj) const {
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 @@ CallStaticJavaNode* ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptR
}
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 ||

@ -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 @@ public:
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;
};

@ -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 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
// 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 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
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

@ -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 @@ void StringConcat::eliminate_initialize(InitializeNode* init) {
// 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 @@ bool StringConcat::validate_control_flow() {
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 @@ bool StringConcat::validate_control_flow() {
// 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);
}