mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
6982537: Crash in Node*step_through_mergemem
Reviewed-by: kvn
This commit is contained in:
parent
0f31511718
commit
f4b4eae617
2 changed files with 19 additions and 17 deletions
|
@ -706,14 +706,15 @@ PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, Gro
|
||||||
//
|
//
|
||||||
// The next methods are derived from methods in MemNode.
|
// The next methods are derived from methods in MemNode.
|
||||||
//
|
//
|
||||||
static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *tinst) {
|
static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop) {
|
||||||
Node *mem = mmem;
|
Node *mem = mmem;
|
||||||
// TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally
|
// TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally
|
||||||
// means an array I have not precisely typed yet. Do not do any
|
// means an array I have not precisely typed yet. Do not do any
|
||||||
// alias stuff with it any time soon.
|
// alias stuff with it any time soon.
|
||||||
if( tinst->base() != Type::AnyPtr &&
|
if( toop->base() != Type::AnyPtr &&
|
||||||
!(tinst->klass()->is_java_lang_Object() &&
|
!(toop->klass() != NULL &&
|
||||||
tinst->offset() == Type::OffsetBot) ) {
|
toop->klass()->is_java_lang_Object() &&
|
||||||
|
toop->offset() == Type::OffsetBot) ) {
|
||||||
mem = mmem->memory_at(alias_idx);
|
mem = mmem->memory_at(alias_idx);
|
||||||
// Update input if it is progress over what we have now
|
// Update input if it is progress over what we have now
|
||||||
}
|
}
|
||||||
|
@ -803,8 +804,8 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
|
||||||
if (orig_mem == NULL)
|
if (orig_mem == NULL)
|
||||||
return orig_mem;
|
return orig_mem;
|
||||||
Compile* C = phase->C;
|
Compile* C = phase->C;
|
||||||
const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
|
const TypeOopPtr *toop = C->get_adr_type(alias_idx)->isa_oopptr();
|
||||||
bool is_instance = (tinst != NULL) && tinst->is_known_instance();
|
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(TypeFunc::Memory);
|
||||||
Node *prev = NULL;
|
Node *prev = NULL;
|
||||||
Node *result = orig_mem;
|
Node *result = orig_mem;
|
||||||
|
@ -827,18 +828,18 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
|
||||||
// skip over a call which does not affect this memory slice
|
// skip over a call which does not affect this memory slice
|
||||||
if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
|
if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
|
||||||
Node *proj_in = result->in(0);
|
Node *proj_in = result->in(0);
|
||||||
if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) {
|
if (proj_in->is_Allocate() && proj_in->_idx == (uint)toop->instance_id()) {
|
||||||
break; // hit one of our sentinels
|
break; // hit one of our sentinels
|
||||||
} else if (proj_in->is_Call()) {
|
} else if (proj_in->is_Call()) {
|
||||||
CallNode *call = proj_in->as_Call();
|
CallNode *call = proj_in->as_Call();
|
||||||
if (!call->may_modify(tinst, phase)) {
|
if (!call->may_modify(toop, phase)) {
|
||||||
result = call->in(TypeFunc::Memory);
|
result = call->in(TypeFunc::Memory);
|
||||||
}
|
}
|
||||||
} else if (proj_in->is_Initialize()) {
|
} else if (proj_in->is_Initialize()) {
|
||||||
AllocateNode* alloc = proj_in->as_Initialize()->allocation();
|
AllocateNode* alloc = proj_in->as_Initialize()->allocation();
|
||||||
// Stop if this is the initialization for the object instance which
|
// Stop if this is the initialization for the object instance which
|
||||||
// which contains this memory slice, otherwise skip over it.
|
// which contains this memory slice, otherwise skip over it.
|
||||||
if (alloc == NULL || alloc->_idx != (uint)tinst->instance_id()) {
|
if (alloc == NULL || alloc->_idx != (uint)toop->instance_id()) {
|
||||||
result = proj_in->in(TypeFunc::Memory);
|
result = proj_in->in(TypeFunc::Memory);
|
||||||
}
|
}
|
||||||
} else if (proj_in->is_MemBar()) {
|
} else if (proj_in->is_MemBar()) {
|
||||||
|
@ -846,7 +847,7 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
|
||||||
}
|
}
|
||||||
} else if (result->is_MergeMem()) {
|
} else if (result->is_MergeMem()) {
|
||||||
MergeMemNode *mmem = result->as_MergeMem();
|
MergeMemNode *mmem = result->as_MergeMem();
|
||||||
result = step_through_mergemem(mmem, alias_idx, tinst);
|
result = step_through_mergemem(mmem, alias_idx, toop);
|
||||||
if (result == mmem->base_memory()) {
|
if (result == mmem->base_memory()) {
|
||||||
// Didn't find instance memory, search through general slice recursively.
|
// Didn't find instance memory, search through general slice recursively.
|
||||||
result = mmem->memory_at(C->get_general_index(alias_idx));
|
result = mmem->memory_at(C->get_general_index(alias_idx));
|
||||||
|
@ -866,7 +867,7 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (result->is_ClearArray()) {
|
} else if (result->is_ClearArray()) {
|
||||||
if (!ClearArrayNode::step_through(&result, (uint)tinst->instance_id(), phase)) {
|
if (!ClearArrayNode::step_through(&result, (uint)toop->instance_id(), phase)) {
|
||||||
// Can not bypass initialization of the instance
|
// Can not bypass initialization of the instance
|
||||||
// we are looking for.
|
// we are looking for.
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -193,14 +193,15 @@ static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally
|
// TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally
|
||||||
// means an array I have not precisely typed yet. Do not do any
|
// means an array I have not precisely typed yet. Do not do any
|
||||||
// alias stuff with it any time soon.
|
// alias stuff with it any time soon.
|
||||||
const TypeOopPtr *tinst = tp->isa_oopptr();
|
const TypeOopPtr *toop = tp->isa_oopptr();
|
||||||
if( tp->base() != Type::AnyPtr &&
|
if( tp->base() != Type::AnyPtr &&
|
||||||
!(tinst &&
|
!(toop &&
|
||||||
tinst->klass()->is_java_lang_Object() &&
|
toop->klass() != NULL &&
|
||||||
tinst->offset() == Type::OffsetBot) ) {
|
toop->klass()->is_java_lang_Object() &&
|
||||||
|
toop->offset() == Type::OffsetBot) ) {
|
||||||
// compress paths and change unreachable cycles to TOP
|
// compress paths and change unreachable cycles to TOP
|
||||||
// If not, we can update the input infinitely along a MergeMem cycle
|
// If not, we can update the input infinitely along a MergeMem cycle
|
||||||
// Equivalent code in PhiNode::Ideal
|
// Equivalent code in PhiNode::Ideal
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue