Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8324969: C2: prevent elimination of unbalanced coarsened locking regions #17697

Closed
wants to merge 10 commits into from
13 changes: 13 additions & 0 deletions src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
@@ -4868,10 +4868,21 @@ void Compile::add_coarsened_locks(GrowableArray<AbstractLockNode*>& locks) {
if (length > 0) {
// Have to keep this list until locks elimination during Macro nodes elimination.
Lock_List* locks_list = new (comp_arena()) Lock_List(comp_arena(), length);
#ifdef ASSERT
AbstractLockNode* alock = locks.at(0);
BoxLockNode* box = alock->box_node()->as_BoxLock();
#endif
for (int i = 0; i < length; i++) {
AbstractLockNode* lock = locks.at(i);
assert(lock->is_coarsened(), "expecting only coarsened AbstractLock nodes, but got '%s'[%d] node", lock->Name(), lock->_idx);
locks_list->push(lock);
#ifdef ASSERT
BoxLockNode* this_box = lock->box_node()->as_BoxLock();
if (this_box != box) {
this_box->mark_unbalanced();
box->mark_unbalanced();
}
#endif
}
_coarsened_locks.append(locks_list);
}
@@ -4974,8 +4985,10 @@ void Compile::mark_unbalanced_boxes() {
if (box != this_box) {
box->set_unbalanced();
this_box->set_unbalanced();
assert(this_box->is_marked_unbalanced(),"inconsistency");
}
}
assert(box->is_unbalanced() == box->is_marked_unbalanced(),"inconsistency");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you even move this a scope out, i.e. a line down, so this check is even run with alock->is_coarsened() == false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. It will verify that we did not miss is_unbalanced() check when do EA or nested elimination to avoid them.

I will also move the assert at line 4984 under (box != this_box) to avoid duplication of check when box is the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving assert down does not work because Nested lock elimination and EA can overwrite Coarsened status for BoxLock before we run mark_unbalanced_boxes(). Such BoxLock will not be marked as Unbalanced and assert will fail.
I would like to keep current assert in place but add an other assert when we change status of BoxLock. I am working on it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, sounds good :)

}
}
}
1 change: 1 addition & 0 deletions src/hotspot/share/opto/locknode.cpp
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ uint BoxLockNode::size_of() const { return sizeof(*this); }

BoxLockNode::BoxLockNode( int slot ) : Node( Compile::current()->root() ),
_slot(slot), _kind(BoxLockNode::Regular) {
DEBUG_ONLY(_marked_unbalanced = false);
init_class_id(Class_BoxLock);
init_flags(Flag_rematerialize);
OptoReg::Name reg = OptoReg::stack2reg(_slot);
8 changes: 8 additions & 0 deletions src/hotspot/share/opto/locknode.hpp
Original file line number Diff line number Diff line change
@@ -42,6 +42,9 @@ class BoxLockNode : public Node {
Eliminated // All lock/unlock in region were eliminated
} _kind;

// In debug VM verify correctness of unbalanced marking
DEBUG_ONLY(bool _marked_unbalanced;)

public:
BoxLockNode( int lock );
virtual int Opcode() const;
@@ -67,6 +70,11 @@ class BoxLockNode : public Node {
void set_eliminated() { _kind = Eliminated; }
void set_unbalanced() { _kind = Unbalanced; }

#ifdef ASSERT
void mark_unbalanced() { _marked_unbalanced = true; }
bool is_marked_unbalanced() const { return _marked_unbalanced; }
#endif

// Is BoxLock node used for one simple lock region?
bool is_simple_lock_region(LockNode** unique_lock, Node* obj, Node** bad_lock);