提交 cb60707e 编写于 作者: K kvn

7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity

Summary: Mark all associated (same box and obj) lock and unlock nodes for elimination if some of them marked already.
Reviewed-by: iveresov, never
上级 39049773
......@@ -1747,6 +1747,25 @@ bool ConnectionGraph::compute_escape() {
_collecting = false;
assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
if (EliminateLocks) {
// Mark locks before changing ideal graph.
int cnt = C->macro_count();
for( int i=0; i < cnt; i++ ) {
Node *n = C->macro_node(i);
if (n->is_AbstractLock()) { // Lock and Unlock nodes
AbstractLockNode* alock = n->as_AbstractLock();
if (!alock->is_eliminated()) {
PointsToNode::EscapeState es = escape_state(alock->obj_node());
assert(es != PointsToNode::UnknownEscape, "should know");
if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
// Mark it eliminated
alock->set_eliminated();
}
}
}
}
}
#ifndef PRODUCT
if (PrintEscapeAnalysis) {
dump(); // Dump ConnectionGraph
......
......@@ -1693,25 +1693,31 @@ void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) {
OptoRuntime::new_array_Java());
}
// we have determined that this lock/unlock can be eliminated, we simply
// eliminate the node without expanding it.
//
// Note: The membar's associated with the lock/unlock are currently not
// eliminated. This should be investigated as a future enhancement.
//
bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
//-----------------------mark_eliminated_locking_nodes-----------------------
// During EA obj may point to several objects but after few ideal graph
// transformations (CCP) it may point to only one non escaping object
// (but still using phi), corresponding locks and unlocks will be marked
// for elimination. Later obj could be replaced with a new node (new phi)
// and which does not have escape information. And later after some graph
// reshape other locks and unlocks (which were not marked for elimination
// before) are connected to this new obj (phi) but they still will not be
// marked for elimination since new obj has no escape information.
// Mark all associated (same box and obj) lock and unlock nodes for
// elimination if some of them marked already.
void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
if (!alock->is_eliminated()) {
return false;
return;
}
if (alock->is_Lock() && !alock->is_coarsened()) {
if (!alock->is_coarsened()) { // Eliminated by EA
// Create new "eliminated" BoxLock node and use it
// in monitor debug info for the same object.
BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
Node* obj = alock->obj_node();
if (!oldbox->is_eliminated()) {
BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
// Note: BoxLock node is marked eliminated only here
// and it is used to indicate that all associated lock
// and unlock nodes are marked for elimination.
newbox->set_eliminated();
transform_later(newbox);
// Replace old box node with new box for all users
......@@ -1720,22 +1726,14 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
bool next_edge = true;
Node* u = oldbox->raw_out(i);
if (u == alock) {
i++;
continue; // It will be removed below
}
if (u->is_Lock() &&
u->as_Lock()->obj_node() == obj &&
// oldbox could be referenced in debug info also
u->as_Lock()->box_node() == oldbox) {
assert(u->as_Lock()->is_eliminated(), "sanity");
if (u->is_AbstractLock() &&
u->as_AbstractLock()->obj_node() == obj &&
u->as_AbstractLock()->box_node() == oldbox) {
// Mark all associated locks and unlocks.
u->as_AbstractLock()->set_eliminated();
_igvn.hash_delete(u);
u->set_req(TypeFunc::Parms + 1, newbox);
next_edge = false;
#ifdef ASSERT
} else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
assert(u->as_Unlock()->is_eliminated(), "sanity");
#endif
}
// Replace old box in monitor debug info.
if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
......@@ -1761,8 +1759,27 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
if (next_edge) i++;
} // for (uint i = 0; i < oldbox->outcnt();)
} // if (!oldbox->is_eliminated())
} // if (alock->is_Lock() && !lock->is_coarsened())
} // if (!alock->is_coarsened())
}
// we have determined that this lock/unlock can be eliminated, we simply
// eliminate the node without expanding it.
//
// Note: The membar's associated with the lock/unlock are currently not
// eliminated. This should be investigated as a future enhancement.
//
bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
if (!alock->is_eliminated()) {
return false;
}
#ifdef ASSERT
if (alock->is_Lock() && !alock->is_coarsened()) {
// Check that new "eliminated" BoxLock node is created.
BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
assert(oldbox->is_eliminated(), "should be done already");
}
#endif
CompileLog* log = C->log();
if (log != NULL) {
log->head("eliminate_lock lock='%d'",
......@@ -2145,6 +2162,15 @@ bool PhaseMacroExpand::expand_macro_nodes() {
if (C->macro_count() == 0)
return false;
// First, attempt to eliminate locks
int cnt = C->macro_count();
for (int i=0; i < cnt; i++) {
Node *n = C->macro_node(i);
if (n->is_AbstractLock()) { // Lock and Unlock nodes
// Before elimination mark all associated (same box and obj)
// lock and unlock nodes.
mark_eliminated_locking_nodes(n->as_AbstractLock());
}
}
bool progress = true;
while (progress) {
progress = false;
......
......@@ -92,6 +92,7 @@ private:
void process_users_of_allocation(AllocateNode *alloc);
void eliminate_card_mark(Node *cm);
void mark_eliminated_locking_nodes(AbstractLockNode *alock);
bool eliminate_locking_node(AbstractLockNode *alock);
void expand_lock_node(LockNode *lock);
void expand_unlock_node(UnlockNode *unlock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册