mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +02:00
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
Mark all associated (same box and obj) lock and unlock nodes for elimination if some of them marked already. Reviewed-by: iveresov, never
This commit is contained in:
parent
a664e486bd
commit
18dd7131d0
3 changed files with 71 additions and 25 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue